StudyLyon — multi-tenant ERP / School Management API. This package designs the
Auth module client (Flutter, forward-looking spec) against the implemented NestJS
backend. All endpoints, DTO fields, schemas, events, rate limits, and wire contracts
are derived directly from src/modules/auth/**, src/common/**, src/modules/rbac/**,
and src/infrastructure/**. No feature is invented; gaps are flagged in the
Assumptions & Open Questions section.
Auth is the entry gate to every StudyLyon surface. It establishes who you are
(identity), which tenant you act in (multi-tenancy), which roles/permissions you
carry (RBAC), and manages the security artifacts that keep every subsequent request safe:
JWT access/refresh token pairs, session registry, password credentials (Argon2id),
email verification, TOTP 2FA, and scoped API keys for machine access.
Anonymous visitor: register a new institution + admin account in one step, land inside with working tokens (register returns tokens at institution).
School admin: daily painless login, device overview + per-device logout, 2FA on, keys to integrations.
Teacher / Staff / Parent / Student: quiet, reliable login; password reset that survive lost passwords; never re-enter credentials more than once a session.
Platform admin: cross-tenant tool access via platform_admin role; impersonation is (planned).
StudyLyon is multi-tenant: one codebase, thousands of schools. A flawed auth gate is the
single highest-risk component (credential leaks, cross-tenant access, account takeover).
This module is the flagship because every other module trusts its tokens.
Mobile client is forward-looking: backend is complete; this package is the UI-side spec.
"Email verification mandatory before first login" is the target FIXED WIRE contract
(docs/blueprint security policy) but is not enforced by auth.service.ts today —
register() mints tokens immediately and login() never checks emailVerified
(auth.service.ts:54,123). UI must anticipate a "verify your email" interstitial and
hard log-in gating as soon as the server enforces it (OQ-1).
2FA challenge during login (a "2FA step" after password) is not implemented in the
backend; login returns tokens directly. Current code only supports 2FA as an account
setting (enable/verify/disable). The 2FA-challenge screen is speced as (planned) /
(forward-looking) and should only be reached when the server returns a challenge signal.
Registration carries tenantId in the body (register.dto.ts:26-29) — a deliberate
exception to "tenantId from token" for the tenant-bootstrap flow.
No QR-code backend endpoint exists — the 2FA QR image is generated on-device from the
returned secret/qrCodeUri (totp qrCodeUri is an otpauth:// URI, auth.service.ts:330).