syncova-policies/scripts/lib/admin-account.js
Weapie 328f042307 Syncova Policies: Portal für DSGVO-Datenschutzerklärungen
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>
2026-09-07 16:23:51 +02:00

62 lines
1.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 }