mirror of
https://github.com/guyg1474/hcrb.git
synced 2026-10-15 23:13:28 +02:00
Rollen (Admin/Mitglied), Seite Kooperationen, Textanpassungen
- Gemeinsame Zugänge mit Rollen: Admin darf alles, Mitglied nutzt Kalender, Fahrtplaner, Treffpunkte und bearbeitet Mitglieder (kein Hinzufügen, Löschen, Import, keine Patches, keine Statistik-Korrektur) - Server prüft die Rechte (403), Konten ohne Rolle gelten als Admin - npm run user: add <name> [admin|mitglied], role <name> <rolle> - Neue öffentliche Seite Kooperationen mit Titelbild, Anführer, Social-Media-Links und Beschreibung, Pflege durch Admin - Kopfzeile bleibt bei mittlerer Breite einzeilig - Texte auf Wunsch gekürzt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f46016487d
commit
819219fb2d
18 files changed
+661
-106
No files matched your search
+31
-10
@@ -1,12 +1,15 @@
|
||||
// Benutzerverwaltung für den Login
|
||||
//
|
||||
// npm run user -- list
|
||||
// npm run user -- add <name> Benutzer anlegen (Passwort wird abgefragt)
|
||||
// npm run user -- passwd <name> Passwort ändern (meldet alle Sitzungen des Benutzers ab)
|
||||
// npm run user -- remove <name> Benutzer löschen
|
||||
// Die Konten sind gemeinsame Zugänge (z. B. "admin" und "hcrb" für alle Mitglieder), keine persönlichen.
|
||||
//
|
||||
// npm run user -- list alle Benutzer mit Rolle
|
||||
// npm run user -- add <name> [admin|mitglied] Benutzer anlegen (Standard: mitglied, Passwort wird abgefragt)
|
||||
// npm run user -- role <name> <admin|mitglied> Rolle ändern (meldet alle Sitzungen des Benutzers ab)
|
||||
// npm run user -- passwd <name> Passwort ändern (meldet alle Sitzungen des Benutzers ab)
|
||||
// npm run user -- remove <name> Benutzer löschen
|
||||
|
||||
import { createInterface } from 'node:readline';
|
||||
import { hashPassword, readUsers, writeUsers, normalizeName, MIN_PASSWORD, USERS_FILE } from '../auth.js';
|
||||
import { hashPassword, readUsers, writeUsers, normalizeName, MIN_PASSWORD, USERS_FILE, ROLES, roleOf } from '../auth.js';
|
||||
|
||||
// Passwort verdeckt einlesen (bei umgeleiteter Eingabe zeilenweise)
|
||||
let pipedLines;
|
||||
@@ -52,22 +55,40 @@ async function newPassword() {
|
||||
return hashPassword(pw);
|
||||
}
|
||||
|
||||
const [cmd, rawName] = process.argv.slice(2);
|
||||
const [cmd, rawName, rawRole] = process.argv.slice(2);
|
||||
const role = String(rawRole ?? '').trim().toLowerCase();
|
||||
|
||||
function checkRole(value) {
|
||||
if (!ROLES.includes(value)) throw new Error(`Rolle muss ${ROLES.join(' oder ')} sein.`);
|
||||
return value;
|
||||
}
|
||||
const name = normalizeName(rawName);
|
||||
const users = readUsers();
|
||||
const user = users.find((u) => u.name === name);
|
||||
|
||||
try {
|
||||
if (cmd === 'list') {
|
||||
console.log(users.length ? users.map((u) => u.name).join('\n') : 'Noch keine Benutzer angelegt.');
|
||||
console.log(users.length
|
||||
? users.map((u) => `${u.name.padEnd(20)} ${roleOf(u)}${u.role ? '' : ' (noch ohne Rolle gespeichert)'}`).join('\n')
|
||||
: 'Noch keine Benutzer angelegt.');
|
||||
} else if (cmd === 'add' && name) {
|
||||
if (!/^[a-z0-9._-]{2,32}$/.test(name)) {
|
||||
throw new Error('Benutzername: 2–32 Zeichen, nur a–z, 0–9, Punkt, Minus, Unterstrich.');
|
||||
}
|
||||
if (user) throw new Error(`Benutzer „${name}“ gibt es schon.`);
|
||||
users.push({ name, hash: await newPassword(), changedAt: Date.now() });
|
||||
const newRole = checkRole(role || 'mitglied');
|
||||
users.push({ name, role: newRole, hash: await newPassword(), changedAt: Date.now() });
|
||||
writeUsers(users);
|
||||
console.log(`Benutzer „${name}“ angelegt.`);
|
||||
console.log(`Benutzer „${name}“ als ${newRole} angelegt.`);
|
||||
} else if (cmd === 'role' && name && role) {
|
||||
if (!user) throw new Error(`Benutzer „${name}“ gibt es nicht.`);
|
||||
user.role = checkRole(role);
|
||||
if (user.role === 'mitglied' && !users.some((u) => roleOf(u) === 'admin')) {
|
||||
throw new Error('Das ist der letzte Admin. Lege zuerst einen anderen Admin an.');
|
||||
}
|
||||
user.changedAt = Date.now();
|
||||
writeUsers(users);
|
||||
console.log(`„${name}“ ist jetzt ${user.role}. Bestehende Anmeldungen sind abgemeldet.`);
|
||||
} else if (cmd === 'passwd' && name) {
|
||||
if (!user) throw new Error(`Benutzer „${name}“ gibt es nicht.`);
|
||||
user.hash = await newPassword();
|
||||
@@ -79,7 +100,7 @@ try {
|
||||
writeUsers(users.filter((u) => u !== user));
|
||||
console.log(`Benutzer „${name}“ gelöscht.`);
|
||||
} else {
|
||||
console.log('Benutzung: npm run user -- list | add <name> | passwd <name> | remove <name>');
|
||||
console.log('Benutzung: npm run user -- list | add <name> [admin|mitglied] | role <name> <admin|mitglied> | passwd <name> | remove <name>');
|
||||
console.log(`Benutzerdatei: ${USERS_FILE}`);
|
||||
process.exitCode = cmd ? 1 : 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user