Next.js 15 App Router mit öffentlicher Übersicht und geschütztem Admin-Bereich zur Pflege von Datenschutzerklärungen nach Art. 12ff. DSGVO. - Oberfläche auf Basis von shadcn/ui, Inter lokal eingebunden - Prisma/SQLite, Auth.js mit Credentials-Provider und Rollen - Massenimport der Merkblätter des Amtes Leezen aus PDF - Docker-Image (standalone) und Gitea-Workflow zur Veröffentlichung Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
62 lines
1.9 KiB
JavaScript
62 lines
1.9 KiB
JavaScript
const crypto = require("crypto")
|
||
const fs = require("fs")
|
||
const path = require("path")
|
||
|
||
/** Liest .env ohne zusätzliche Abhängigkeit ein (überschreibt keine echten ENV-Variablen). */
|
||
function loadEnv() {
|
||
const envPath = path.join(__dirname, "..", "..", ".env")
|
||
if (!fs.existsSync(envPath)) return
|
||
|
||
for (const line of fs.readFileSync(envPath, "utf8").split(/\r?\n/)) {
|
||
const match = line.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*)\s*$/)
|
||
if (!match) continue
|
||
|
||
const [, key, rawValue] = match
|
||
if (process.env[key] !== undefined) continue
|
||
|
||
process.env[key] = rawValue.replace(/^["']|["']$/g, "")
|
||
}
|
||
}
|
||
|
||
/** Erzeugt ein Passwort mit garantiert je einem Zeichen aus allen vier Klassen. */
|
||
function generatePassword(length = 18) {
|
||
const upper = "ABCDEFGHJKLMNPQRSTUVWXYZ"
|
||
const lower = "abcdefghijkmnopqrstuvwxyz"
|
||
const digits = "23456789"
|
||
const symbols = "!@#$%&*-_+=?"
|
||
const pool = upper + lower + digits + symbols
|
||
|
||
const chars = [
|
||
upper[crypto.randomInt(upper.length)],
|
||
lower[crypto.randomInt(lower.length)],
|
||
digits[crypto.randomInt(digits.length)],
|
||
symbols[crypto.randomInt(symbols.length)],
|
||
]
|
||
|
||
while (chars.length < length) {
|
||
chars.push(pool[crypto.randomInt(pool.length)])
|
||
}
|
||
|
||
// Fisher-Yates
|
||
for (let i = chars.length - 1; i > 0; i--) {
|
||
const j = crypto.randomInt(i + 1)
|
||
;[chars[i], chars[j]] = [chars[j], chars[i]]
|
||
}
|
||
|
||
return chars.join("")
|
||
}
|
||
|
||
function printCredentials({ email, password, action }) {
|
||
const line = "─".repeat(52)
|
||
console.log(`\n${line}`)
|
||
console.log(` Admin-Zugang ${action}`)
|
||
console.log(line)
|
||
console.log(` E-Mail: ${email}`)
|
||
console.log(` Passwort: ${password}`)
|
||
console.log(line)
|
||
console.log(" Bitte jetzt im Passwortmanager speichern –")
|
||
console.log(" das Passwort wird nirgends im Klartext abgelegt.\n")
|
||
}
|
||
|
||
module.exports = { loadEnv, generatePassword, printCredentials }
|