mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 13:36:48 +00:00
feat(auth): explain the plain-HTTP secure-cookie gotcha on login
When the server issues a Secure session cookie but the request arrived over plain HTTP (the common LAN install over http://ip:3000), the browser drops the cookie and the next request dead-ends on a bare "Access token required" — the top source of avoidable install issues. The login response now flags this exact case and the login page shows a localized box explaining the fix (use HTTPS, or set COOKIE_SECURE=false) with a link to the Troubleshooting guide. It only triggers in the real failure case, never for correct HTTPS setups.
This commit is contained in:
@@ -4,6 +4,7 @@ import { AuthService } from './auth.service';
|
||||
import { RateLimitService } from './rate-limit.service';
|
||||
import { OptionalJwtGuard } from './optional-jwt.guard';
|
||||
import { writeAudit, getClientIp } from '../../services/auditLog';
|
||||
import { willDropSecureCookie } from '../../services/cookie';
|
||||
import type { User } from '../../types';
|
||||
|
||||
const WINDOW = 15 * 60 * 1000;
|
||||
@@ -88,7 +89,13 @@ export class AuthPublicController {
|
||||
return { mfa_required: true, mfa_token: result.mfa_token };
|
||||
}
|
||||
this.auth.setAuthCookie(res, result.token!, req, result.remember);
|
||||
return { token: result.token, user: result.user };
|
||||
return {
|
||||
token: result.token,
|
||||
user: result.user,
|
||||
// Surfaced so the client can explain the plain-HTTP cookie gotcha instead
|
||||
// of the user hitting a bare "Access token required" on the next request.
|
||||
...(willDropSecureCookie(req) ? { insecureCookie: true } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@Post('forgot-password')
|
||||
|
||||
@@ -54,6 +54,22 @@ function buildOptions(clear: boolean, secure: boolean, remember?: RememberOption
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* True when we are about to set a `Secure` session cookie but the request did
|
||||
* NOT arrive over HTTPS — the browser silently drops the cookie, so the next
|
||||
* request has no session and the server answers "Access token required". This is
|
||||
* the classic plain-HTTP install gotcha; callers surface it to the user with a
|
||||
* concrete fix (use HTTPS or set COOKIE_SECURE=false) instead of a bare 401.
|
||||
*/
|
||||
export function willDropSecureCookie(req?: Request): boolean {
|
||||
if (process.env.COOKIE_SECURE?.toLowerCase() === 'false') return false;
|
||||
if (req?.secure === true) return false;
|
||||
return (
|
||||
process.env.NODE_ENV?.toLowerCase() === 'production' ||
|
||||
process.env.FORCE_HTTPS?.toLowerCase() === 'true'
|
||||
);
|
||||
}
|
||||
|
||||
export function setAuthCookie(res: Response, token: string, req?: Request, remember?: RememberOption): void {
|
||||
res.cookie(COOKIE_NAME, token, cookieOptions(false, req, remember));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user