import { env, createLogger } from '@4runr/shared';
import * as crypto from 'crypto';
const logger = createLogger('Gateway:Auth:JWT');
function verifyJwt(token, secret, algorithm = 'HS256') {
    try {
        const parts = token.split('.');
        if (parts.length !== 3) {
            return null;
        }
        const [headerB64, payloadB64, signatureB64] = parts;
        const signatureCheck = crypto
            .createHmac(algorithm.toLowerCase().replace('hs', 'sha'), secret)
            .update(`${headerB64}.${payloadB64}`)
            .digest('base64url');
        if (signatureCheck !== signatureB64) {
            return null;
        }
        if (!payloadB64) {
            return null;
        }
        const payload = JSON.parse(Buffer.from(payloadB64, 'base64url').toString('utf8'));
        if (payload.exp && Date.now() >= payload.exp * 1000) {
            return null;
        }
        return payload;
    }
    catch (error) {
        logger.error('JWT verification error', { error: error instanceof Error ? error.message : String(error) });
        return null;
    }
}
export async function requireJwt(request, reply) {
    const authorization = request.headers.authorization;
    if (!authorization || !authorization.startsWith('Bearer ')) {
        reply.status(401).send({
            error: 'unauthorized',
            reason: 'invalid_or_missing_credentials',
            message: 'Missing or invalid Authorization header. Expected: Authorization: Bearer <token>',
        });
        return;
    }
    const token = authorization.substring(7);
    if (!env.JWT_SECRET) {
        reply.status(500).send({
            error: 'server_error',
            message: 'JWT authentication is not configured',
        });
        return;
    }
    const decoded = verifyJwt(token, env.JWT_SECRET, env.JWT_ALG);
    if (!decoded) {
        reply.status(401).send({
            error: 'unauthorized',
            reason: 'invalid_or_missing_credentials',
            message: 'Invalid or expired JWT token',
        });
        return;
    }
    request.auth = decoded;
    request.user = decoded;
}
export async function optionalJwt(request, reply) {
    const authorization = request.headers.authorization;
    if (authorization && authorization.startsWith('Bearer ')) {
        const token = authorization.substring(7);
        if (env.JWT_SECRET) {
            const decoded = verifyJwt(token, env.JWT_SECRET, env.JWT_ALG);
            if (decoded) {
                request.auth = decoded;
                request.user = decoded;
            }
        }
    }
}
//# sourceMappingURL=authJwt.js.map