import { inject } from '@angular/core'; import { CanActivateFn, Router } from '@angular/router'; import { AccessStore } from '@shared/application/access.store'; import { SESSION_PORT } from '@shared/application/session.port'; import { Capability } from '@shared/domain/capability'; /** * Route guards, shared by both apps (ADR-C-006). * * These are deliberately **not** part of the `auth` context that ADR-0002 §3 keeps * duplicated per app. That decision scopes to *identity and login flow* — `Principal`, * DigiD vs. employee SSO. A route guard is neither: it asks only "is anyone logged in" * and "may they do X", never "who are you or how did you get here". Both questions are * answered through seams that already live here — `SESSION_PORT` and `AccessStore` — so * the guards never see an actor type and have nothing to diverge on. * * Each app re-exports these from its own `auth/auth.guard.ts`, so `app.routes.ts` keeps * importing `@auth/auth.guard` and the context boundary reads unchanged. */ /** Route guard: only let authenticated users in; otherwise redirect to /login. */ export const authGuard: CanActivateFn = () => { const session = inject(SESSION_PORT); const router = inject(Router); return session.isAuthenticated() ? true : router.createUrlTree(['/login']); }; /** * Route guard factory (PRD-0002 §6): authenticated AND holding `capability`, else * redirect. Used by the admin pages (`/brief/huisstijl`, `/beheer/stamdata`). * * **Async on purpose:** `can()` is deny-by-default, so it must not be read while `/me` * is still loading — it would deny an entitled admin and bounce them. We await * `AccessStore.whenReady()` (caps resolved) before deciding. An unauthenticated user * goes to `/login`; an authenticated-but-unentitled user goes to `/dashboard` (they're * logged in, just not allowed here — no re-login loop). The backend re-enforces * regardless (403); this guard is the UX pre-gate. */ export function capabilityGuard(capability: Capability): CanActivateFn { return async () => { const session = inject(SESSION_PORT); const access = inject(AccessStore); const router = inject(Router); if (!session.isAuthenticated()) return router.createUrlTree(['/login']); await access.whenReady(); return access.can(capability) ? true : router.createUrlTree(['/dashboard']); }; }