auth
@mmm/auth
Monorepo für die Auth-Domain mit klar getrennten Bereichen für Verträge, Angular-UI, NestJS-Server und Prisma.
Struktur
contractsFrameworkfreie Auth-Verträge und gemeinsame Transporttypen.frontendAngular-basierte UI-Bausteine für Auth, Routing und Authorization.backendNestJS-basierte Server-Bausteine für Core-, Password-, OAuth- und OIDC-Authentifizierung.prismaPrisma-spezifische Artefakte der Auth-Domain.legacyHistorische Referenz. Neue Struktur und neue Imports dürfen davon nicht abhängen.
Architekturregeln
contractsbleibt frameworkfrei.frontenddarfcontractsverwenden, aber kein NestJS- oder Prisma-spezifisches Verhalten enthalten.backenddarfcontractsverwenden, aber kein Angular-spezifisches Verhalten enthalten.permissionsdarfbackendverwenden, aber kein Angular-spezifisches Verhalten enthalten.prismaist optionaler Infrastrukturteil und bleibt von UI und Server entkoppelt.- Auth und Authorization bleiben getrennt geschnitten.
- Provider-spezifische Themen liegen unter
password,oauthundoidc, nicht verstreut über Legacy-Pfade.
Öffentliche Entry Points
@mmm/auth/contracts@mmm/auth/contracts/core@mmm/auth/contracts/password@mmm/auth/contracts/oauth@mmm/auth/ui@mmm/auth/server@mmm/auth/server/core@mmm/auth/server/password@mmm/auth/server/oauth@mmm/auth/server/oidc@mmm/auth/server/permissions@mmm/auth/prisma
Kompatibilitäts-Exports für ./frontend und ./backend bleiben vorerst erhalten, sollten aber mittelfristig durch ./ui und ./server ersetzt werden.
Build
pnpm run buildDas baut in Reihenfolge:
contractsfrontendbackendpermissions
Beispiel UI
import { AuthUiModule } from "@mmm/auth/ui";
AuthUiModule.forRoot({ core: { apiBaseUrl: "/api", tokenStorage: "sessionStorage", }, password: { loginEndpoint: "/auth/login", postLoginRedirectUrl: "/", }, oauth: { enabledProviders: ["microsoft"], postLoginRedirectUrl: "/", },});Beispiel Server
import { AuthServerModule } from "@mmm/auth/server";
AuthServerModule.forRootAsync({ jwt: { secret: jwtSecret }, core: { inject: [PRISMA_CLIENT], useFactory: (prisma: PrismaClient) => ({ resolver: new PrismaAuthResolver(prisma), options: { rolling: { enabled: true, accessTokenTtlSeconds: sessionLength, renewWhenSecondsLeft: sessionLength, }, }, }), }, password: { inject: [PRISMA_CLIENT], useFactory: (prisma: PrismaClient) => ({ validator: new PrismaPasswordValidator(prisma), options: { accessTokenTtlSeconds: sessionLength, renewWhenSecondsLeft: sessionLength, }, }), }, oauth: { inject: [PRISMA_CLIENT], useFactory: (prisma: PrismaClient) => ({ resolver: new PrismaAuthOAuthResolver(prisma), options: { backendBaseUrl: process.env.BACKEND_BASE_URL!, frontendBaseUrl: process.env.FRONTEND_BASE_URL!, frontendCallbackPath: "/login/callback", providers: { microsoft: { flowType: "oauth2_oidc", clientId: process.env.MICROSOFT_OAUTH_CLIENT_ID!, clientSecret: process.env.MICROSOFT_OAUTH_CLIENT_SECRET!, }, }, }, }), },});