ADR-0002 SS3 models Zorgverlener/Medewerker as different Principal variants with different login flows. Actor #2 (apps/behandelportal) landed in WP-61/67 and the union never followed: grep -rn "Principal" returned one hit, a comment. Both apps' auth/domain/session.ts stayed byte-identical (`{ bsn, naam }`), so the backoffice's Behandelaar carried a BSN and logged into the backoffice as a citizen, by DigiD, under a fabricated citizen's name (login.page.ts). The divergence ADR-0002 predicted took an orthogonal side door instead (medewerker.interceptor.ts's X-Medewerker/X-Rollen stamp, which never touches SessionStore) -- which is why ssp/auth and bhp/auth still measured as 100%/84% duplicated after ADR-C-006 shared the route guards. RB-09 (landed the day before) made the backend's IIdentityProvider able to say "no identity" and fail closed; this ticket is its named FE half. Each app's auth/domain/session.ts becomes principal.ts, holding the one Principal variant that app actually has an actor for: ssp keeps `{ kind: 'zorgverlener', bsn, naam }` (G1 still strips the BSN before persisting); behandelportal gets `{ kind: 'medewerker', medewerkerId, naam, rollen }` (no BSN to strip -- G2 shape validation only). A new MedewerkerAdapter replaces DigidAdapter in behandelportal, resolving the existing MEDEWERKER_ID/currentRollen() dev stand-in into a Principal; because there is no credential to check, it returns Principal directly rather than a Result whose error variant could never occur. login.page.ts stops being a BSN/wachtwoord form -- one explainer line and an "Inloggen met SSO" button -- and its dead error-handling branch goes with the Result wrapper that justified it. Measured with tools/baseline-scan.mjs --dup: auth duplication drops from 168/168 (ssp) and 168/200 (bhp) to 32/179 and 32/259 -- under the backlog's <40 target. What remains is the ADR-C-006 route-guard re-export (deliberately identical), generic test/story-file boilerplate, and one shared fragment of the root-singleton-store idiom -- not re-converged identity or login-flow logic. SS3's prediction that the two actors would authenticate differently enough to justify not sharing auth has now actually been tested, not just asserted, and held. Also: renamed Session.bsn to Principal.bsn in two doc comments (libs/shared/src/infrastructure/subject.ts, subject.interceptor.ts) that cited the old type name; regenerated libs/shared/docs/behaviour-spec.mdx (generated file, per its own banner); recorded the resolution in ADR-0002 as a new amendment, replacing its "Known debt" section. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
import { Component, inject } from '@angular/core';
|
|
import { Router } from '@angular/router';
|
|
import { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';
|
|
import { LoginFormComponent } from '@auth/ui/login-form/login-form.component';
|
|
import { SessionStore } from '@auth/application/session.store';
|
|
|
|
/**
|
|
* No error alert here — unlike the SSP's DigiD form, `SessionStore.login()` has
|
|
* nothing to fail on (see `MedewerkerAdapter`). A real SSO integration is where
|
|
* this page would grow one back.
|
|
*/
|
|
@Component({
|
|
selector: 'app-login-page',
|
|
imports: [PageShellComponent, LoginFormComponent],
|
|
template: `
|
|
<app-page-shell
|
|
i18n-heading="@@login.heading"
|
|
heading="Inloggen bij het behandelportal"
|
|
width="narrow"
|
|
i18n-intro="@@login.intro"
|
|
intro="Voor medewerkers die aanvragen beoordelen."
|
|
>
|
|
<app-login-form (submitted)="login()" />
|
|
</app-page-shell>
|
|
`,
|
|
})
|
|
export class LoginPage {
|
|
private store = inject(SessionStore);
|
|
private router = inject(Router);
|
|
|
|
async login() {
|
|
await this.store.login();
|
|
this.router.navigate(['/dashboard']);
|
|
}
|
|
}
|