// middleware/authCheck.js
const fetch = require("node-fetch");
const { auth } = require("../config/loader");
const { verify: verify_url, cache_ttl, timeout_ms } = auth;
const { LOG_MESSAGES } = require("../constants/authConstants");
// Simple in-memory cache
const authCache = new Map();
function getCacheKey(cookie, authHeader) {
return `${cookie}:${authHeader}`;
}
function isCacheValid(entry) {
return entry && Date.now() - entry.timestamp < cache_ttl;
}
setInterval(() => {
const now = Date.now();
for (const [key, entry] of authCache.entries()) {
if (now - entry.timestamp >= cache_ttl) {
authCache.delete(key);
}
}
}, cache_ttl);
const SAFE_IPS = ["192.168.1.200", "192.168.1.50"];
module.exports = async (req, res, next) => {
// Determine the client IP address.
// req.ip is often provided by Express and correctly handles X-Forwarded-For if Express is configured for it.
// If not, you might need to manually check req.headers['x-forwarded-for']
const clientIp = req.ip; // Or req.headers['x-forwarded-for']?.split(',')[0] || req.connection.remoteAddress;
// --- Bypass Logic ---
// Check if the client IP is in the list of safe IPs
if (SAFE_IPS.includes(clientIp)) {
req.isAuthenticated = true; // Mark as authenticated (bypassed)
if (req.log) {
req.log.security(`Bypassing authentication for safe IP: ${clientIp}`);
} else {
console.security(`Bypassing authentication for safe IP: ${clientIp}`);
}
return next(); // Proceed to the next middleware/route handler
}
// --- End Bypass Logic ---
const cookie = req.headers["cookie"] || "";
const authHeader = req.headers["authorization"] || "";
const cacheKey = getCacheKey(cookie, authHeader);
const cached = authCache.get(cacheKey);
if (isCacheValid(cached)) {
req.isAuthenticated = cached.isAuthenticated;
return next();
}
req.isAuthenticated = false;
try {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), auth.timeout_ms);
const resVerify = await fetch(verify_url, {
headers: { cookie, authorization: authHeader },
credentials: "include",
signal: controller.signal,
});
clearTimeout(timeout);
req.isAuthenticated = resVerify.status === 200;
authCache.set(cacheKey, {
isAuthenticated: req.isAuthenticated,
timestamp: Date.now(),
});
} catch (e) {
req.isAuthenticated = false;
if (req.log) {
req.log.warn(LOG_MESSAGES.AUTH_SERVER_UNAVAILABLE, e.stack);
} else {
console.warn(LOG_MESSAGES.AUTH_SERVER_UNAVAILABLE, e.stack);
}
}
next();
};