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 {
|
||||
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)
|
||||
const { isTokenRevoked } = require('../utils/tokenRevocation');
|
||||
|
||||
Reference in New Issue
Block a user