Wiki/bridge/tests/middleware/scopes.test.ts
Corentin JOGUET 571f5c3426
Some checks are pending
CI / Lint bridge (Biome) (push) Waiting to run
CI / Type-check bridge (push) Blocked by required conditions
CI / Tests unit bridge (push) Blocked by required conditions
CI / Tests integration bridge (push) Blocked by required conditions
CI / Security scan (push) Waiting to run
CI / Docker build + healthcheck (push) Blocked by required conditions
feat(auth): Bloc 4 — middleware OIDC-ready avec dual mode service-token + Authentik JWT
- Support JWT OIDC Authentik via jose + JWKS (cache 10min)
- Lookup Personne via PersonneRepo.findByEmail + cache Redis 60s
- Mapping groups Authentik + roles formation-hub vers scopes
- Mode OIDC active uniquement si AUTHENTIK_ISSUER + JWKS_URI + AUDIENCE set
- Service tokens brg_* inchanges, restent voie principale en local
2026-05-07 21:17:56 +02:00

62 lines
2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
DEFAULT_ROLE_SCOPES,
computeOidcScopes,
parseGroupsScopesMap,
} from '../../src/middleware/scopes.js';
describe('parseGroupsScopesMap', () => {
it('retourne {} si vide', () => {
expect(parseGroupsScopesMap(undefined)).toEqual({});
expect(parseGroupsScopesMap('')).toEqual({});
});
it('parse un mapping valide', () => {
const map = parseGroupsScopesMap('{"g1":["a","b"],"g2":["c"]}');
expect(map).toEqual({ g1: ['a', 'b'], g2: ['c'] });
});
it('throw si JSON invalide', () => {
expect(() => parseGroupsScopesMap('{')).toThrow(/JSON/);
});
it('throw si pas un objet', () => {
expect(() => parseGroupsScopesMap('[1,2]')).toThrow(/objet/);
expect(() => parseGroupsScopesMap('"x"')).toThrow(/objet/);
});
it('throw si valeur pas array of strings', () => {
expect(() => parseGroupsScopesMap('{"g":[1]}')).toThrow();
expect(() => parseGroupsScopesMap('{"g":"x"}')).toThrow();
});
});
describe('computeOidcScopes', () => {
it('union groups + roles + dedup', () => {
const scopes = computeOidcScopes(['formation-hub-formateurs'], new Set(['formateur']), {
'formation-hub-formateurs': ['formation:read', 'admin:custom'],
});
expect(scopes).toContain('formation:read');
expect(scopes).toContain('admin:custom');
// Vient du DEFAULT_ROLE_SCOPES.formateur
expect(scopes).toContain('write:attributions');
});
it("group inconnu ignore (pas d'erreur)", () => {
const scopes = computeOidcScopes(['unknown-group'], new Set(), {});
expect(scopes).toEqual([]);
});
it('default mapping admin role -> admin:*', () => {
const scopes = computeOidcScopes([], new Set(['admin']), {});
expect(scopes).toContain('admin:*');
});
it('aucun group + aucun role = scopes vides', () => {
expect(computeOidcScopes([], new Set(), {})).toEqual([]);
});
it('DEFAULT_ROLE_SCOPES couvre les 5 roles', () => {
expect(Object.keys(DEFAULT_ROLE_SCOPES)).toHaveLength(5);
});
});