-
Notifications
You must be signed in to change notification settings - Fork 0
Authentication
-
Access token: signed with
TOKEN_SECRET, expiryTOKEN_EXP_IN(e.g.3h). -
Refresh token: signed with
TOKEN_REFRESH, expiryTOKEN_REFRESH_EXP_IN(defaults to7dif unset). - Both carry
{ _id: candidateId }as the payload. -
POST /auth/refreshrotates both tokens and blacklists the old refresh token — reusing a rotated-out refresh token is rejected ("Refresh token revoked"/ 403).
Until 2026-08-21, TOKEN_EXP_IN was declared but never actually passed to the JWT signer, so both tokens silently defaulted to a 1-hour expiry each — meaning the refresh token expired at the same time as the access token, making the refresh flow pointless. Fixed; both now honor their configured/default expiries independently.
utils/tokenBlacklist.ts — Redis-backed with an in-memory Map fallback if Redis is unavailable. TTL matches the token's remaining lifetime. A background cleanup job runs every 60s for the in-memory fallback path.
Applied to every /api/v1/* route except /auth/*. On a valid token it:
- Attaches
req.user = { _id }. -
Forces
req.body.candidateId = req.user._id, overwriting whatever the client sent. This is deliberate — see Security for why.
verifyTokenByQuery is the same check but also accepts the token via ?token= (used by /download-pdf, since browsers can't set custom headers on a direct-link download).
Send Accept-Language: en to get English messages; omit the header (or send vi) for Vietnamese (the default, matching pre-i18n behavior). Currently covers the full auth flow (register/login/logout/refresh) — see src/locales/{vi,en}.ts for the exact key set.
Not yet covered: Joi validation error messages, Mongoose required messages, and candidate/CV-section success/error messages — these still always return Vietnamese regardless of Accept-Language. Tracked under issue #78.
# English
curl -X POST .../api/v1/auth/login -H "Accept-Language: en" -d '{"email":"x","password":"wrong-but-valid-format"}'
# → {"message":"Incorrect password", ...}
# Vietnamese (default)
curl -X POST .../api/v1/auth/login -d '{"email":"x","password":"wrong-but-valid-format"}'
# → {"message":"Mật khẩu không chính xác", ...}Enforced via Joi (config/joi.config.ts) and regex (config/regex.config.ts): minimum 12 characters, at least one uppercase, one lowercase, one number, one special character. Hashed with bcrypt at 12 rounds (utils/bcrypt.ts).