mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-25 09:46:47 +00:00
fix(auth): keep active sessions alive and add stay-signed-in (#1711)
This commit is contained in:
@@ -106,6 +106,7 @@ authRouter.post('/setup', authRateLimiter, async (req: Request, res: Response):
|
||||
// Login endpoint
|
||||
authRouter.post('/login', authRateLimiter, async (req: Request, res: Response): Promise<void> => {
|
||||
const { username, password } = req.body;
|
||||
const remember = req.body.remember === true;
|
||||
|
||||
if (!username || !password) {
|
||||
res.status(400).json({ error: 'Username and password are required' });
|
||||
@@ -131,13 +132,13 @@ authRouter.post('/login', authRateLimiter, async (req: Request, res: Response):
|
||||
console.log('[MFA:diag] login: path=local user=', user.username, 'mfaEnabled=', !!mfa?.enabled, 'failedAttempts=', mfa?.failed_attempts ?? 0, 'lockedUntil=', mfa?.locked_until ?? null);
|
||||
}
|
||||
if (mfa?.enabled) {
|
||||
issueMfaPendingCookie(res, req, user, jwtSecret);
|
||||
issueMfaPendingCookie(res, req, user, jwtSecret, { remember });
|
||||
console.log('[Auth] Login password OK, MFA challenge pending:', user.username);
|
||||
res.json({ success: true, mfaRequired: true });
|
||||
return;
|
||||
}
|
||||
|
||||
issueSessionCookie(res, req, user, jwtSecret);
|
||||
issueSessionCookie(res, req, user, jwtSecret, remember);
|
||||
console.log('[Auth] Login successful:', user.username);
|
||||
res.json({ success: true, message: 'Login successful' });
|
||||
return;
|
||||
|
||||
@@ -72,7 +72,7 @@ mfaRouter.post('/login/mfa', authRateLimiter, async (req: Request, res: Response
|
||||
return;
|
||||
}
|
||||
|
||||
let decoded: { scope?: string; user_id?: number; username?: string; sso?: boolean };
|
||||
let decoded: { scope?: string; user_id?: number; username?: string; sso?: boolean; remember?: boolean };
|
||||
try {
|
||||
decoded = jwt.verify(pendingCookie, jwtSecret) as typeof decoded;
|
||||
} catch {
|
||||
@@ -173,7 +173,7 @@ mfaRouter.post('/login/mfa', authRateLimiter, async (req: Request, res: Response
|
||||
|
||||
db.clearMfaFailures(decoded.user_id);
|
||||
clearMfaPendingCookie(res, req);
|
||||
issueSessionCookie(res, req, user, jwtSecret);
|
||||
issueSessionCookie(res, req, user, jwtSecret, decoded.remember === true);
|
||||
console.log('[Auth] MFA challenge cleared:', user.username);
|
||||
if (isDebugEnabled()) console.log('[MFA:diag] login/mfa: success user=', user.username, 'durationMs=', Date.now() - startedAt);
|
||||
res.json({ success: true });
|
||||
|
||||
@@ -36,6 +36,7 @@ const ALLOWED_SETTING_KEYS = new Set([
|
||||
'auto_create_missing_external_networks',
|
||||
'image_update_sidebar_indicators',
|
||||
'notification_dispatch_retries',
|
||||
'session_sliding_refresh',
|
||||
]);
|
||||
|
||||
// Keys whose write requires a paid license, not just an admin role.
|
||||
@@ -77,6 +78,7 @@ const SettingsPatchSchema = z.object({
|
||||
});
|
||||
}
|
||||
}).transform((v) => String(parseNotificationDispatchRetries(v)!)),
|
||||
session_sliding_refresh: z.enum(['0', '1']),
|
||||
}).partial();
|
||||
|
||||
export const settingsRouter = Router();
|
||||
|
||||
@@ -43,6 +43,7 @@ ssoRouter.get('/providers', (_req: Request, res: Response): void => {
|
||||
ssoRouter.post('/ldap', authRateLimiter, async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { username, password } = req.body;
|
||||
const remember = req.body.remember === true;
|
||||
if (!username || !password) {
|
||||
res.status(400).json({ error: 'Username and password are required' });
|
||||
return;
|
||||
@@ -71,13 +72,13 @@ ssoRouter.post('/ldap', authRateLimiter, async (req: Request, res: Response): Pr
|
||||
console.log('[MFA:diag] login: path=ldap user=', user.username, 'mfaEnabled=', !!mfa?.enabled, 'ssoEnforce=', mfa?.sso_enforce_mfa === 1);
|
||||
}
|
||||
if (mfa?.enabled && mfa.sso_enforce_mfa) {
|
||||
issueMfaPendingCookie(res, req, user, settings.auth_jwt_secret, { sso: true });
|
||||
issueMfaPendingCookie(res, req, user, settings.auth_jwt_secret, { sso: true, remember });
|
||||
console.log(`[SSO] LDAP login password OK, MFA challenge pending: ${user.username}`);
|
||||
res.json({ success: true, mfaRequired: true });
|
||||
return;
|
||||
}
|
||||
|
||||
issueSessionCookie(res, req, user, settings.auth_jwt_secret);
|
||||
issueSessionCookie(res, req, user, settings.auth_jwt_secret, remember);
|
||||
console.log(`[SSO] LDAP login successful: ${user.username}`);
|
||||
res.json({ success: true, message: 'Login successful' });
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user