Files
RayLab-Core/tests/unit/jwt-auth.guard.spec.ts
T
Rayyan 6ee7a7cda4
Deploy / deploy (push) Failing after 33s
update
2026-08-09 18:23:58 +07:00

70 lines
2.8 KiB
TypeScript

// Mock 'jose' module before importing JwtAuthGuard so Jest doesn't try to parse ESM from node_modules
let mockJwtVerify: (token: any) => Promise<any> = async () => { throw new Error('no jwks') };
jest.mock('jose', () => ({
createRemoteJWKSet: () => ({}),
jwtVerify: async (token: any, jwks: any, opts: any) => mockJwtVerify(token),
}));
import { JwtAuthGuard } from '../../src/core/auth/guards/jwt-auth.guard';
import { ExecutionContext } from '@nestjs/common';
import * as jwt from 'jsonwebtoken';
// These tests focus on identitySource being set based on verification path.
describe('JwtAuthGuard', () => {
let guard: JwtAuthGuard;
beforeEach(() => {
guard = new JwtAuthGuard();
process.env.RAYLAB_JWT_SECRET = 'test-secret';
delete process.env.AUTHENTIK_JWKS_URI; // ensure JWKS not attempted unless test sets it
// reset mock behavior
mockJwtVerify = async () => { throw new Error('no jwks') };
});
function makeCtxWithAuthHeader(token: string) {
const req: any = { headers: { authorization: `Bearer ${token}` }, cookies: {} };
const ctx: any = { switchToHttp: () => ({ getRequest: () => req }) } as ExecutionContext;
return { ctx, req };
}
test('internal verification sets identitySource=internal', async () => {
const token = jwt.sign({ sub: 'uid', preferred_username: 'u', email: 'e' }, process.env.RAYLAB_JWT_SECRET || 'test-secret');
const { ctx, req } = makeCtxWithAuthHeader(token);
const res = await guard.canActivate(ctx);
expect(res).toBe(true);
expect(req.identity).toBeDefined();
expect((req.identitySource)).toBe('internal');
});
test('external verification sets identitySource=external if JWKS verifies', async () => {
process.env.AUTHENTIK_JWKS_URI = 'https://example.com/.well-known/jwks.json';
// set mock to succeed
mockJwtVerify = async (token: any) => ({ payload: { sub: 'extsub', preferred_username: 'eu', email: 'ee' } });
const token = 'dummy';
const { ctx, req } = makeCtxWithAuthHeader(token);
const res = await guard.canActivate(ctx);
expect(res).toBe(true);
expect(req.identity).toBeDefined();
expect((req.identitySource)).toBe('external');
});
test('external verification fails then internal succeeds -> identitySource=internal', async () => {
process.env.AUTHENTIK_JWKS_URI = 'https://example.com/.well-known/jwks.json';
// make jwks fail
mockJwtVerify = async (token: any) => { throw new Error('jwks fail'); };
const token = jwt.sign({ sub: 'uid2', preferred_username: 'u2', email: 'e2' }, process.env.RAYLAB_JWT_SECRET || 'test-secret');
const { ctx, req } = makeCtxWithAuthHeader(token);
const res = await guard.canActivate(ctx);
expect(res).toBe(true);
expect(req.identity).toBeDefined();
expect((req.identitySource)).toBe('internal');
});
});