import 'server-only' import { z } from 'zod' import { INSTANZEN, type Instanz } from '@/lib/instanz' /** * Jede Einstellung von aussen wird geprueft, bevor sie benutzt wird. Fehlt * etwas Pflichtiges, faellt das beim ersten Zugriff auf – mit einer Meldung, * die den Variablennamen nennt, nie deren Wert. */ const jaNein = z .enum(['true', 'false', '1', '0', 'ja', 'nein']) .transform((w) => w === 'true' || w === '1' || w === 'ja') const schema = z.object({ INSTANZ: z.enum(INSTANZEN), APP_URL: z.url().transform((u) => u.replace(/\/+$/, '')), DATABASE_URL: z.string().min(1), AUTH_SECRET: z.string().min(16, 'AUTH_SECRET ist zu kurz, mindestens 16 Zeichen.'), AUTH_TRUST_HOST: jaNein.default(false), ANMELDUNG_PASSWORT: jaNein.default(false), OIDC_NAME: z.string().trim().default(''), OIDC_ISSUER: z.string().trim().default(''), OIDC_CLIENT_ID: z.string().trim().default(''), OIDC_CLIENT_SECRET: z.string().trim().default(''), WEBAUTHN_RP_ID: z.string().min(1), WEBAUTHN_RP_NAME: z.string().min(1).default('Planer'), WEBAUTHN_ORIGIN: z.url(), DEMO_MODUS: jaNein.default(false), }) export type Umgebung = z.infer & { instanz: Instanz /** OIDC ist nur eingerichtet, wenn alle vier Werte gesetzt sind. */ oidcAktiv: boolean } let zwischengespeichert: Umgebung | null = null function lesen(): Umgebung { const ergebnis = schema.safeParse(process.env) if (!ergebnis.success) { const felder = ergebnis.error.issues .map((f) => `${f.path.join('.')}: ${f.message}`) .join('\n ') throw new Error(`Die Konfiguration ist unvollstaendig:\n ${felder}`) } const werte = ergebnis.data return { ...werte, instanz: werte.INSTANZ, oidcAktiv: Boolean( werte.OIDC_ISSUER && werte.OIDC_CLIENT_ID && werte.OIDC_CLIENT_SECRET, ), } } /** Die geprueften Einstellungen. Erst beim ersten Aufruf ausgewertet. */ export function umgebung(): Umgebung { zwischengespeichert ??= lesen() return zwischengespeichert } /** Nur fuer Tests: erzwingt beim naechsten Aufruf ein erneutes Einlesen. */ export function umgebungVergessen(): void { zwischengespeichert = null }