Current behavior
utils/jwt.js signs a JWT with JWT_SECRET and JWT_EXPIRES_IN (default 7d, see .env.example). middleware/apiAuth.js verifies the signature/expiry on every request and loads the user - there's no other server-side state involved.
Concretely, today:
- Tokens are long-lived (7 days by default) with no refresh flow - a contributor picks a shorter value at their own risk of forcing frequent re-logins.
- There's no revocation path.
POST /api/v1/auth/logout (controllers/api/auth.js) just returns { ok: true } - it doesn't invalidate anything server-side, so a token keeps working after "logout" until it naturally expires.
changePassword and resetPassword (controllers/api/auth.js) don't invalidate previously issued tokens either - a stolen token from before a password change stays valid.
This is a discussion issue, not an implementation task
Please don't open a PR against this without agreement on the approach first - auth changes affect every signed-in extension install.
Define, in the issue thread or a linked doc:
- Current behavior (above, verify against the code as it evolves)
- Identified limitations: no revocation, no refresh, password change doesn't invalidate old tokens
- Desired security properties: e.g., a compromised token should stop working within a bounded time of logout/password change, without breaking the "just works" extension UX
- Proposed approaches: shorter-lived access tokens + refresh tokens, a server-side denylist/version field on the user (e.g. a
tokenVersion bumped on logout/password change and checked in apiAuth), or something else
- Compatibility considerations: existing installed extensions hold long-lived tokens today; any change needs a migration story that doesn't mass-log-out users without warning
Relevant files
utils/jwt.js
middleware/apiAuth.js
controllers/api/auth.js (login, logout, changePassword, resetPassword)
.env.example (JWT_EXPIRES_IN)
docs/authentication.md, docs/security-audit.md (existing write-ups to build on, not duplicate)
Current behavior
utils/jwt.jssigns a JWT withJWT_SECRETandJWT_EXPIRES_IN(default7d, see.env.example).middleware/apiAuth.jsverifies the signature/expiry on every request and loads the user - there's no other server-side state involved.Concretely, today:
POST /api/v1/auth/logout(controllers/api/auth.js) just returns{ ok: true }- it doesn't invalidate anything server-side, so a token keeps working after "logout" until it naturally expires.changePasswordandresetPassword(controllers/api/auth.js) don't invalidate previously issued tokens either - a stolen token from before a password change stays valid.This is a discussion issue, not an implementation task
Please don't open a PR against this without agreement on the approach first - auth changes affect every signed-in extension install.
Define, in the issue thread or a linked doc:
tokenVersionbumped on logout/password change and checked inapiAuth), or something elseRelevant files
utils/jwt.jsmiddleware/apiAuth.jscontrollers/api/auth.js(login,logout,changePassword,resetPassword).env.example(JWT_EXPIRES_IN)docs/authentication.md,docs/security-audit.md(existing write-ups to build on, not duplicate)