All checks were successful
CI / lint (pull_request) Successful in 1m8s
CI / build (pull_request) Successful in 53s
CI / unit (pull_request) Successful in 58s
CI / frontend (pull_request) Successful in 2m10s
CI / mutation (pull_request) Successful in 3m58s
CI / verify-stack (pull_request) Successful in 7m48s
The token-attachment bug (secureRoutes set to the app origin, which a relative api-client URL never matches) was only caught by the full-stack e2e. Add a fast unit guard: drive the REAL angular-auth-oidc-client interceptor and the REAL api-client against the production route value, faking only the config source and the token storage. Asserts the bearer token rides the relative /self-service/ call and is withheld from the anonymous /openbaar/ call. Extract the value to a shared SECURE_API_ROUTES constant so the test binds to exactly what the app configures. Verified the guard fails (Authorization null) if the value regresses to an origin. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
66 lines
2.7 KiB
TypeScript
66 lines
2.7 KiB
TypeScript
import { provideHttpClient, withInterceptors } from '@angular/common/http';
|
|
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
|
import { TestBed } from '@angular/core/testing';
|
|
import { BffApiV1Service } from 'api-client';
|
|
import { authInterceptor } from 'auth';
|
|
import { AbstractSecurityStorage, ConfigurationService } from 'angular-auth-oidc-client';
|
|
import { SECURE_API_ROUTES } from './app.config';
|
|
|
|
// Guards the DigiD token wiring end-to-end. The api-client calls the BFF with RELATIVE URLs, and the
|
|
// angular-auth-oidc-client interceptor attaches the token only when `req.url` starts with a configured
|
|
// secureRoute. A regression to an absolute origin (as once shipped) makes the relative URL never match,
|
|
// so the submit goes out unauthenticated and fails silently. This drives the REAL interceptor and the
|
|
// REAL api-client against the REAL production route value (SECURE_API_ROUTES); only the config source
|
|
// and the token storage are faked, so the assertion turns on the actual route-matching.
|
|
describe('self-service DigiD token wiring', () => {
|
|
let http: HttpTestingController;
|
|
let bff: BffApiV1Service;
|
|
const token = 'digid-access-token';
|
|
|
|
beforeEach(() => {
|
|
TestBed.configureTestingModule({
|
|
providers: [
|
|
provideHttpClient(withInterceptors([authInterceptor()])),
|
|
provideHttpClientTesting(),
|
|
{
|
|
provide: ConfigurationService,
|
|
useValue: {
|
|
hasAtLeastOneConfig: () => true,
|
|
getAllConfigurations: () => [{ configId: 'digid', secureRoutes: SECURE_API_ROUTES }],
|
|
},
|
|
},
|
|
{
|
|
// A signed-in session: the storage the interceptor's token lookup reads from.
|
|
provide: AbstractSecurityStorage,
|
|
useValue: {
|
|
read: () => JSON.stringify({ authzData: token, authnResult: { id_token: 'id-token' } }),
|
|
write: () => undefined,
|
|
remove: () => undefined,
|
|
clear: () => undefined,
|
|
},
|
|
},
|
|
],
|
|
});
|
|
http = TestBed.inject(HttpTestingController);
|
|
bff = TestBed.inject(BffApiV1Service);
|
|
});
|
|
|
|
afterEach(() => http.verify());
|
|
|
|
it('attaches the bearer token to the relative self-service BFF call', () => {
|
|
bff.postSelfServiceRegistrations().subscribe();
|
|
|
|
const req = http.expectOne('/self-service/registrations');
|
|
expect(req.request.headers.get('Authorization')).toBe(`Bearer ${token}`);
|
|
req.flush({ registrationId: 'reg-1', status: 'Ingediend' });
|
|
});
|
|
|
|
it('leaves the anonymous openbaar register call unauthenticated', () => {
|
|
bff.getOpenbaarRegister().subscribe();
|
|
|
|
const req = http.expectOne((r) => r.url === '/openbaar/register');
|
|
expect(req.request.headers.has('Authorization')).toBe(false);
|
|
req.flush([]);
|
|
});
|
|
});
|