"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const node_crypto_1 = require("node:crypto");
const jose_1 = require("jose");
const vitest_1 = require("vitest");
const verifier_js_1 = require("./verifier.js");
const KEY_ID = 'test-key';
const createSigningMaterial = (kid = KEY_ID) => {
    const { publicKey, privateKey } = (0, node_crypto_1.generateKeyPairSync)('rsa', {
        modulusLength: 2048
    });
    const jwk = {
        ...publicKey.export({ format: 'jwk' }),
        kid,
        alg: 'RS256',
        use: 'sig'
    };
    return {
        jwk,
        privateKeyPem: privateKey.export({ type: 'pkcs8', format: 'pem' }).toString()
    };
};
const buildJwtVerifier = (jwk) => {
    const getKeysInterceptor = vitest_1.vi.fn(async () => [jwk]);
    const options = {
        jwksUri: 'https://example.com/.well-known/jwks.json',
        cache: false,
        getKeysInterceptor
    };
    return { verifier: new verifier_js_1.JwtVerifier(options), getKeysInterceptor };
};
(0, vitest_1.describe)('JwtVerifier', () => {
    let signingMaterial;
    (0, vitest_1.beforeAll)(() => {
        signingMaterial = createSigningMaterial();
    });
    (0, vitest_1.it)('verifies a token with a matching JWKS entry', async () => {
        const { verifier, getKeysInterceptor } = buildJwtVerifier(signingMaterial.jwk);
        const payload = {
            sub: 'user-123',
            scope: 'read:all'
        };
        const key = await (0, jose_1.importPKCS8)(signingMaterial.privateKeyPem, 'RS256');
        const token = await new jose_1.SignJWT(payload).setProtectedHeader({ alg: 'RS256', kid: signingMaterial.jwk.kid }).sign(key);
        const result = await verifier.verify(token);
        (0, vitest_1.expect)(getKeysInterceptor).toHaveBeenCalledTimes(1);
        (0, vitest_1.expect)(result.sub).toBe(payload.sub);
        (0, vitest_1.expect)(result.scope).toBe(payload.scope);
    });
    (0, vitest_1.it)('throws UnauthorizedError when the signature does not match the JWKS entry', async () => {
        const { verifier } = buildJwtVerifier(signingMaterial.jwk);
        const mismatchedKey = createSigningMaterial();
        const invalidKey = await (0, jose_1.importPKCS8)(mismatchedKey.privateKeyPem, 'RS256');
        const invalidToken = await new jose_1.SignJWT({ sub: 'user-456' })
            .setProtectedHeader({ alg: 'RS256', kid: signingMaterial.jwk.kid })
            .sign(invalidKey);
        await (0, vitest_1.expect)(verifier.verify(invalidToken)).rejects.toMatchObject({
            status: 401,
            message: vitest_1.expect.stringContaining('signature verification failed')
        });
    });
    (0, vitest_1.it)('honors JwtVerifyOptions when audience and issuer match', async () => {
        const { verifier, getKeysInterceptor } = buildJwtVerifier(signingMaterial.jwk);
        const audience = 'target-app';
        const issuer = 'https://issuer.example.com';
        const key = await (0, jose_1.importPKCS8)(signingMaterial.privateKeyPem, 'RS256');
        const token = await new jose_1.SignJWT({ sub: 'user-789' })
            .setProtectedHeader({ alg: 'RS256', kid: signingMaterial.jwk.kid })
            .setAudience(audience)
            .setIssuer(issuer)
            .sign(key);
        const result = await verifier.verify(token, {
            algorithms: ['RS256'],
            audience,
            issuer
        });
        (0, vitest_1.expect)(getKeysInterceptor).toHaveBeenCalledTimes(1);
        (0, vitest_1.expect)(result.sub).toBe('user-789');
        (0, vitest_1.expect)(result.aud).toBe(audience);
        (0, vitest_1.expect)(result.iss).toBe(issuer);
    });
    (0, vitest_1.it)('rejects when VerifyOptions constraints fail', async () => {
        const { verifier } = buildJwtVerifier(signingMaterial.jwk);
        const audience = 'target-app';
        const issuer = 'https://issuer.example.com';
        const key = await (0, jose_1.importPKCS8)(signingMaterial.privateKeyPem, 'RS256');
        const token = await new jose_1.SignJWT({ sub: 'user-987' })
            .setProtectedHeader({ alg: 'RS256', kid: signingMaterial.jwk.kid })
            .setAudience(audience)
            .setIssuer(issuer)
            .sign(key);
        await (0, vitest_1.expect)(verifier.verify(token, {
            algorithms: ['RS256'],
            audience: `${audience}-mismatch`,
            issuer
        })).rejects.toMatchObject({
            status: 401,
            message: vitest_1.expect.stringContaining('unexpected "aud" claim value')
        });
    });
    (0, vitest_1.it)('rejects malformed tokens before attempting JWKS lookup', async () => {
        const { verifier, getKeysInterceptor } = buildJwtVerifier(signingMaterial.jwk);
        await (0, vitest_1.expect)(verifier.verify('definitely-not-a-jwt')).rejects.toThrow('Invalid token specified');
        (0, vitest_1.expect)(getKeysInterceptor).not.toHaveBeenCalled();
    });
});
//# sourceMappingURL=verifier.test.js.map