Authentication System Guide
Docklift uses a token-based authentication system (JWT) to secure the API and frontend.
Components
- Routes:
backend/src/routes/auth.ts - Middleware:
backend/src/lib/authMiddleware.ts - Frontend Context:
frontend/components/AuthProvider.tsx - Frontend API Helper:
frontend/lib/auth.ts - Database Model:
User(email, password hash, role).
Auth Flow
Registration:
POST /api/auth/register- Only allows registration if zero users exist in the database (first user becomes admin).
Login:
POST /api/auth/login- Validates email/password (bcrypt, 12 salt rounds).
- Returns a JWT
token(7-day expiry). - Rate limited via
express-rate-limiton all/api/authroutes.
Session Management:
- Frontend stores the token in
localStoragekeydocklift_token. - Token is sent in
Authorization: Bearer <token>header viagetAuthHeaders()infrontend/lib/auth.ts. AuthProvider.tsxvalidates the token against/api/auth/meon page load and clears invalid tokens.
- Frontend stores the token in
Protected Routes
All routes except the following require JWT via authMiddleware:
/api/auth/register,/api/auth/login,/api/auth/status(public, rate limited)/api/github/webhook,/callback,/manifest/callback,/setup(GitHub flow)/api/backup/restore-uploadwith valid one-time setup token (fresh install restore)
Routes /me, /profile, /change-password all use authMiddleware (not manual JWT decoding).
SSE Authentication
Server-Sent Events (logs, deployment streams) use short-lived tokens instead of long-lived JWTs in URLs:
POST /api/auth/sse-token→ returns a 5-minute JWT withpurpose: 'sse'- Frontend uses this token as a query parameter:
?token=<sseToken> - Backend validates
purpose === 'sse'before allowing SSE connections
Security Middleware
Located in backend/src/lib/authMiddleware.ts.
authenticateToken: Verifies JWT signature, attachesreq.user, returns 401 if invalid.
Security Hardening
- Error Sanitization: All
catchblocks in auth routes return generic messages (e.g.,'Login failed'), nevererror.message. - Security Headers: Applied globally via
helmet()middleware inindex.ts. - CORS: Configured from
CORS_ORIGINenvironment variable. - Rate Limiting: Applied to all
/api/authroutes. - Terminal: WebSocket JWT + password re-verification (double auth).
- Backup Downloads: Use
fetch+Authorization: Bearerheader + blob download pattern — never put JWTs in URL query parameters (prevents token leakage in browser history, server logs, and referrer headers).
Passwords
- Hashing: Uses
bcryptwith 12 salt rounds. - Reset: Admin password can be reset via CLI:
cd backend bun run reset-password
Common Issues
- Infinite Redirects: Often caused by invalid token storage or clock skew invalidating JWTs.
- "Unauthorized" Loop: Frontend not clearing invalid token — clear
localStorage.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.