fix(auth): return JSON 401 for API sessions and harden cross-site cookies

This commit is contained in:
Adolfo Reyna
2026-02-21 21:55:01 -05:00
parent a8ddae4b1e
commit 83727957ab
5 changed files with 72 additions and 19 deletions

View File

@@ -1,12 +1,49 @@
const isProduction = process.env.NODE_ENV === "production";
const forceSecureCookie = process.env.COOKIE_SECURE === "true";
const secure = forceSecureCookie || isProduction;
const cookiesOptions = {
maxAge: 1000 * 60 * 60 * 24 * 90, // would expire after 90 days
httpOnly: true, // The cookie only accessible by the web server
sameSite: secure ? 'none' : 'lax',
secure,
const COOKIE_MAX_AGE_MS = 1000 * 60 * 60 * 24 * 90; // 90 days
const LOCAL_ORIGIN_REGEX = /^http:\/\/(localhost|127\.0\.0\.1|aeropi\.local)(:\d+)?$/i;
const LOCAL_HOST_REGEX = /^(localhost|127\.0\.0\.1|aeropi\.local)(:\d+)?$/i;
const getHeaderValue = (req, key) => {
if (!req || !req.headers) return "";
const raw = req.headers[key];
if (Array.isArray(raw)) return raw[0] || "";
return raw || "";
};
module.exports = { cookiesOptions };
const isLocalRequest = (req) => {
const origin = getHeaderValue(req, "origin");
const host = getHeaderValue(req, "host");
return LOCAL_ORIGIN_REGEX.test(origin) || LOCAL_HOST_REGEX.test(host);
};
const isHttpsRequest = (req) => {
if (!req) return false;
const forwardedProto = String(getHeaderValue(req, "x-forwarded-proto")).split(",")[0].trim().toLowerCase();
const reqProtocol = String(req.protocol || "").toLowerCase();
const origin = String(getHeaderValue(req, "origin") || "").toLowerCase();
if (forwardedProto === "https" || reqProtocol === "https") return true;
return origin.startsWith("https://");
};
const shouldUseSecureCookie = (req) => {
if (forceSecureCookie) return true;
if (isLocalRequest(req)) return false;
if (isHttpsRequest(req)) return true;
return isProduction;
};
const getCookiesOptions = (req) => {
const secure = shouldUseSecureCookie(req);
return {
maxAge: COOKIE_MAX_AGE_MS,
httpOnly: true,
sameSite: secure ? "none" : "lax",
secure,
};
};
const cookiesOptions = getCookiesOptions();
module.exports = { cookiesOptions, getCookiesOptions };

View File

@@ -7,6 +7,7 @@ var corsOptions = {
'http://127.0.0.1:8081',
'http://localhost:3000',
"https://social.emmint.com",
"https://www.social.emmint.com",
"https://fellowship.emmint.com",
"https://aeropi.local",
],