Julien Gautier b34a22f8c1
CI / commits (pull_request) Successful in 2m39s
CI / scan (pull_request) Successful in 2m48s
CI / check (pull_request) Successful in 2m57s
CI / a11y (pull_request) Successful in 2m14s
CI / perf (pull_request) Successful in 5m48s
feat(portal-bff): close the auth loop — callback persists session, /me, RP-initiated /logout
callback now writes the resolved AuthenticatedUser into
req.session.user and waits for req.session.save() before the 302 so
the spa lands on the post-login page with a populated session
already on redis. without the awaited save, connect-redis can race
the spa's subsequent /me call.

GET /auth/me returns the curated public subset of the session user
(oid / tid / username / displayName) or 401 with
{"error":"unauthenticated"}. amr and other internal claims stay
server-side — the @requireMfa() guard (adr-0011) and the audit
pipeline (adr-0013) consume them directly off the session.

GET /auth/logout destroys the redis-side session, clears the
session cookie (sessionCookieName() so it matches what the middleware
set — __Host-portal_session in prod, portal_session in dev), then
302s to entra's /oauth2/v2.0/logout?post_logout_redirect_uri=… so
the idp-side session is killed too (rp-initiated logout per
adr-0009). id_token_hint is deliberately omitted in v1: the
id_token isn't persisted in the session yet (adr-0014 dependency),
and the account-picker is a safer default in the interim.

logout is idempotent: anonymous users get the same redirect, the
session.destroy() is a no-op. a redis-side destroy failure is
logged via pino as event=session.destroy_failed and the cookie is
cleared anyway — orphan redis keys hit their idle ttl on their own.

a small typescript module augmentation in session/session.types.ts
declares req.session.user so every consumer sees a typed payload
instead of `unknown`. side-effect imported by session.module.ts to
keep it in the compile graph.

out of scope, landing in follow-ups:
- absolute-timeout interceptor (12 h hard ceiling, adr-0010)
- user_sessions:{userId} secondary index (admin "logout everywhere")
- encrypted tokens blob in the session (id_token, access_token,
  refresh_token — adr-0014)
- csrf middleware (phase-2 security)
2026-05-12 19:43:33 +02:00

Documentation index

This is the entry point to all project documentation. It is maintained automatically: any addition, rename, or removal of a .md file under docs/ must be reflected here in the same change.

Conventions

  • Documentation is written in English.
  • One topic per file. Group related files into a folder when there are three or more.
  • Cross-reference with relative links so they keep working in GitHub, IDEs, and exported sites.
  • For architectural decisions, do not add them here — they belong in decisions/ as MADR 4.0.0 ADRs.

Sections

Daily development

  • development.md — repo layout, prerequisites, initial setup, daily commands, observability dev-loop (Jaeger UI, log ↔ trace correlation), dependency updates (Renovate), conventional commit cycle. Day-to-day reference for working on the project.

Architecture

  • architecture.md — cross-cutting Mermaid diagrams: C4 system context, C4 containers, Nx module boundaries, CI/CD pipeline. Single-decision diagrams (auth sequence, ERD, etc.) live inline in their ADR.

Onboarding & environment

Setup guides for new contributors:

Operations & runbooks

Empty — to be populated when we deploy.

Security, performance, accessibility

Empty — placeholders to be filled with rationale docs alongside their corresponding ADRs.

S
Description
No description provided
Readme 42 MiB
Languages
TypeScript 85.3%
JavaScript 5.4%
SCSS 4.3%
HTML 3.9%
Shell 0.8%
Other 0.3%