import crypto from 'node:crypto';
const IS_PROD = process.env.NODE_ENV === 'production';
const AUTH_FAIL_DELAY_MS = 1000;
const MAX_ATTEMPTS_PER_IP = 10;
const ATTEMPT_WINDOW_MS = 300_000;
const SESSION_DURATION_MS = 86_400_000;
const authAttempts = new Map();
const sessions = new Map();
function generateSessionToken() {
    return crypto.randomBytes(32).toString('hex');
}
function cleanExpiredSessions() {
    const now = Date.now();
    for (const [token, session] of sessions) {
        if (session.expiresAt < now) {
            sessions.delete(token);
        }
    }
}
export function createSession(ip) {
    cleanExpiredSessions();
    const token = generateSessionToken();
    const session = {
        token,
        createdAt: Date.now(),
        expiresAt: Date.now() + SESSION_DURATION_MS,
        ip,
    };
    sessions.set(token, session);
    return session;
}
export function getSession(token) {
    cleanExpiredSessions();
    const session = sessions.get(token);
    if (session && session.expiresAt < Date.now()) {
        sessions.delete(token);
        return undefined;
    }
    return session;
}
export function destroySession(token) {
    sessions.delete(token);
}
const UNAUTHORIZED = 'Nao autorizado. Forneca token de administrador valido.';
const TOKEN_NOT_CONFIGURED = 'Token de administrador (TUTANUS_ADMIN_TOKEN) nao configurado.';
export function exigeAutenticacao(req, res, next) {
    const token = process.env.TUTANUS_ADMIN_TOKEN;
    if (!token) {
        if (IS_PROD) {
            res.status(401).json({ erro: TOKEN_NOT_CONFIGURED });
            return;
        }
        next();
        return;
    }
    const ip = req.ip || req.socket.remoteAddress || 'unknown';
    const now = Date.now();
    let attemptData = authAttempts.get(ip);
    if (!attemptData || now > attemptData.windowStart + ATTEMPT_WINDOW_MS) {
        attemptData = { count: 0, windowStart: now };
        authAttempts.set(ip, attemptData);
    }
    if (attemptData.count >= MAX_ATTEMPTS_PER_IP) {
        res.status(429).json({ erro: 'Muitas tentativas de autenticacao. Tente novamente mais tarde.' });
        return;
    }
    const authHeader = req.headers.authorization;
    const cookieToken = req.headers.cookie
        ?.split(';')
        .map(c => c.trim())
        .find(c => c.startsWith('session_token='))
        ?.split('=')[1];
    const session = cookieToken ? getSession(cookieToken) : undefined;
    if (session && session.ip === ip) {
        next();
        return;
    }
    if (authHeader && authHeader.startsWith('Bearer ') && authHeader.slice(7) === token) {
        attemptData.count++;
        next();
        return;
    }
    attemptData.count++;
    setTimeout(() => {
        res.status(401).json({ erro: UNAUTHORIZED });
    }, AUTH_FAIL_DELAY_MS);
}
//# sourceMappingURL=autenticacao.js.map