fix(auth): make /auth/session verify the issuer claim like adminAuth (#350)
Asymmetric JWT verification was causing a /admin/login → /admin/dashboard
→ /admin/login redirect loop for users carrying admin cookies issued
before the iss: 'picpeak-auth' claim was added (commit 23cd9cb,
"address Shannon security assessment findings (37 vulnerabilities)").
The frontend uses GET /auth/session as the source of truth for "is the
user authenticated?". That endpoint called jwt.verify(token, JWT_SECRET)
with no issuer option, so it accepted pre-issuer tokens and reported
valid: true. AdminLoginPage then redirected to /admin/dashboard, every
protected endpoint went through adminAuth which DOES verify the issuer,
each one rejected the token with 401, the response interceptor
window.location.href'd back to /admin/login, and the loop closed.
Fix: pass { issuer: 'picpeak-auth' } to /auth/session's jwt.verify so it
matches adminAuth and galleryAuth. Tokens without the claim now correctly
return valid: false from the session check, AdminLoginPage shows the
login form, and a fresh login mints a properly-issued cookie.
The other intentionally-lax verify call sites (logout-flow logging,
photoAuth, sessionTimeout, rateLimit) are unrelated to the loop and stay
lax — their callers don't gate "authenticated?" decisions on the result.
Reproducer: open a removed/archived gallery URL with a stale admin
cookie from before the issuer claim was added, click "Back to home" on
the gallery-not-found page → loop.
This commit is contained in:
@@ -483,7 +483,14 @@ router.get('/session', async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
// Verify with the same `issuer` claim that adminAuth/galleryAuth
|
||||||
|
// require (#350 — without this, /auth/session accepted pre-issuer
|
||||||
|
// tokens and the frontend thought the user was authenticated, but
|
||||||
|
// every protected endpoint rejected them with 401, producing a
|
||||||
|
// /admin/login → /admin/dashboard → /admin/login redirect loop).
|
||||||
|
const decoded = jwt.verify(token, process.env.JWT_SECRET, {
|
||||||
|
issuer: 'picpeak-auth'
|
||||||
|
});
|
||||||
|
|
||||||
// Check if token has been revoked (e.g. after logout)
|
// Check if token has been revoked (e.g. after logout)
|
||||||
const { isTokenRevoked } = require('../utils/tokenRevocation');
|
const { isTokenRevoked } = require('../utils/tokenRevocation');
|
||||||
|
|||||||
Reference in New Issue
Block a user