Re-validate JWT against the DB in isLoggedIn (fixes #12) #16

Merged
whitlocktech merged 2 commits from fix/stale-jwt-revalidation into main 2026-07-03 02:32:08 +00:00

View File

@@ -2,6 +2,7 @@ const jwt = require('jsonwebtoken')
require('dotenv').config()
const log = require('./logger')('auth')
const users = require('../model/users/users.model')
const JWT_SECRET = process.env.JWT_SECRET
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '1d'
@@ -77,12 +78,22 @@ function getUserFromRequest(req) {
return verifyToken(token)
}
// Gate middleware for protected (admin) routes.
function isLoggedIn(req, res, next) {
const user = getUserFromRequest(req)
if (!user) return res.status(401).json({ message: 'Unauthorized' })
req.user = user
return next()
// Gate middleware for protected (admin) routes. Re-validates the token against
// the database on every request so a demoted or deleted user loses access
// immediately, instead of keeping their old role (or a working session) until
// the JWT expires. req.user carries the fresh DB row, not the token payload.
async function isLoggedIn(req, res, next) {
const decoded = getUserFromRequest(req)
if (!decoded) return res.status(401).json({ message: 'Unauthorized' })
try {
const user = await users.getById(decoded.id)
if (!user) return res.status(401).json({ message: 'Unauthorized' }) // deleted since token issued
req.user = user
return next()
} catch (err) {
log.error('isLoggedIn', err)
return res.status(500).json({ message: 'Internal Server Error' })
}
}
// Gate middleware factory: allow only the listed roles. Assumes isLoggedIn ran