Files
AfiS-Aktensystem/packages/db/src/loadEnv.ts
T
Harlekin 3c3b71d175 Callback-URL aus APP_URL ableiten
Auth.js baut die redirect_uri nicht aus dem Host-Header, sondern aus AUTH_URL.
Ohne die Variable bleibt sie fest auf http://localhost:3000 - hinter dem
Cloudflare Tunnel wäre die Anmeldung damit kaputt gewesen, und zwar mit einer
Fehlermeldung von Discord, die nicht auf die Ursache zeigt. APP_URL ist ohnehin
die kanonische öffentliche Adresse und wird jetzt durchgereicht.

Nachweis mit dem gebauten Standalone-Server: mit gesetztem APP_URL kommt
https://afis.example.de/api/auth/callback/discord heraus, ohne fällt sie auf
localhost zurück. Ein E2E-Test hält Scope identify, state, PKCE mit S256 und
den Pfad der Callback-URL fest.

Nebenbefund, eigenständig behoben: loadEnvFromRepoRoot hat gesetzte
Umgebungsvariablen mit den Werten der Entwicklungs-.env überschrieben.
process.loadEnvFile tut das von sich aus. Eine .env ist ein Rückfall für die
lokale Entwicklung, kein Vorrang vor dem, was der Aufrufer ausdrücklich
mitgibt - sonst überschreibt sie etwa die APP_URL eines Testlaufs und die
Fehlersuche führt weit weg von der Ursache.
2026-09-01 19:37:09 +02:00

34 lines
1.2 KiB
TypeScript

import { existsSync } from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
/**
* Prisma 7 liest die .env nicht mehr von selbst, und Seed und Tests laufen
* ausserhalb von Next.js. Im Betrieb kommen die Werte aus dem .env-Reiter von
* Dockge und stehen längst in der Umgebung, dann passiert hier nichts.
*
* Bereits gesetzte Variablen werden **nicht** überschrieben. `process.loadEnvFile`
* tut das von sich aus, und das ist an dieser Stelle falsch: eine .env ist ein
* Rückfall für die lokale Entwicklung, kein Vorrang vor dem, was der Aufrufer
* ausdrücklich mitgegeben hat. Sonst überschreibt sie zum Beispiel die APP_URL
* eines Testlaufs, und die Fehlersuche führt weit weg von der Ursache.
*/
export function loadEnvFromRepoRoot(): void {
const here = path.dirname(fileURLToPath(import.meta.url))
const candidates = [
path.resolve(here, '../../../.env'),
path.resolve(here, '../../.env'),
path.resolve(process.cwd(), '.env'),
]
const file = candidates.find((candidate) => existsSync(candidate))
if (!file) return
const before = new Map(Object.entries(process.env))
process.loadEnvFile(file)
for (const [key, value] of before) {
if (value !== undefined) process.env[key] = value
}
}