fix: resolve redirect loop after mandatory password change (#263)

After changing password, the backend sets password_changed_at which
invalidates the old JWT token. But the frontend still holds the old
token in the HttpOnly cookie, so the next session check returns 401,
triggering an infinite redirect loop between /admin/login and
/admin/dashboard.

Fix: issue a new JWT token cookie after successful password change
so the session remains valid without requiring re-login.
This commit is contained in:
Paul Nothaft
2026-04-05 18:33:46 +02:00
parent aef9b4ed7f
commit 3c8d344ddd
+16
View File
@@ -1,5 +1,6 @@
const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const { body } = require('express-validator');
const { db, logActivity } = require('../database/db');
const { adminAuth } = require('../middleware/auth');
@@ -7,6 +8,7 @@ const { endSession } = require('../middleware/sessionTimeout');
const { validatePasswordStrength } = require('../utils/passwordGenerator');
const { handleAsync, validateRequest, successResponse } = require('../utils/routeHelpers');
const { NotFoundError, ConflictError, ValidationError } = require('../utils/errors');
const { setAdminAuthCookie } = require('../utils/tokenUtils');
const router = express.Router();
// Get admin profile
@@ -133,6 +135,20 @@ router.post('/change-password', [
updated_at: now
});
// Issue a new token so the session remains valid after password_changed_at invalidated the old one
const newToken = jwt.sign({
id: user.id,
username: user.username,
type: 'admin',
role: user.role_name,
loginTime: Date.now()
}, process.env.JWT_SECRET, {
expiresIn: '24h',
issuer: 'picpeak-auth'
});
setAdminAuthCookie(res, newToken);
// Log activity
await logActivity('password_changed',
{ admin_id: userId },