import { getSecurityHeaders } from './headers.js';
import { validateToken as validateCsrf } from './csrf.js';
/** Compose a security middleware pipeline that applies headers, CSRF, and rate limiting. */
export async function applySecurityMiddleware(request, config) {
    const responseHeaders = getSecurityHeaders(config.headers);
    if (config.rateLimit) {
        const key = config.rateLimitKey?.(request) ?? getClientIp(request);
        const result = await config.rateLimit.check(key);
        if (!result.allowed) {
            return {
                allowed: false,
                headers: responseHeaders,
                error: 'Rate limit exceeded',
                status: 429,
            };
        }
        responseHeaders['X-RateLimit-Remaining'] = String(result.remaining);
        responseHeaders['X-RateLimit-Reset'] = result.resetAt.toISOString();
    }
    if (config.csrf?.enabled && isMutatingMethod(request.method)) {
        const csrfToken = request.headers.get('x-csrf-token') ?? '';
        const cookieName = config.csrf.cookieName ?? '__actuate_csrf';
        const storedToken = parseCookie(request.headers.get('cookie') ?? '', cookieName);
        if (!storedToken || !validateCsrf(csrfToken, storedToken)) {
            return {
                allowed: false,
                headers: responseHeaders,
                error: 'Invalid CSRF token',
                status: 403,
            };
        }
    }
    return { allowed: true, headers: responseHeaders };
}
function isMutatingMethod(method) {
    return ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method.toUpperCase());
}
function getClientIp(request) {
    return request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? 'unknown';
}
function parseCookie(cookieHeader, name) {
    const match = cookieHeader.match(new RegExp(`(?:^|;\\s*)${name}=([^;]*)`));
    return match?.[1];
}
//# sourceMappingURL=middleware.js.map