Mitarbeiter-Passwörter auf 25 Zeichen (BSI-Empfehlung)
Portal-Customer-Schwellwert bleibt 12 (Handy-Eingabe → längere PWs
erhöhen Reuse-Risiko). Mitarbeiter/Admin nutzen Passwort-Manager,
für die kostet die Länge nichts.
passwordGenerator.ts:
- STAFF_MIN_PASSWORD_LENGTH = 25, PORTAL_MIN_PASSWORD_LENGTH = 12
- validatePasswordComplexity({ minLength }) parametrisiert
Mitarbeiter-Pfade auf 25:
- createUser, register, setUserPassword
- confirmPasswordReset: Audience aus Token bestimmen
(getPasswordResetAudience), User → 25, Customer → 12. Kein
Body-Hint, damit kein Downgrade-Trick möglich.
Portal-Pfade unverändert (default 12):
- setPortalPassword, changeInitialPortalPassword
Seed-Admin:
- 28-char Zufallspasswort (statt 16) mit allen 4 Klassen garantiert
- SEED_ADMIN_PASSWORD-ENV nur akzeptiert wenn ≥ 25 Zeichen,
sonst Log-Warnung + Random-Fallback
Frontend:
- UserList: Hinweis "Mind. 25 Zeichen". Update + PW gleichzeitig →
zwei API-Calls (PUT + POST /users/:id/password) statt
Password im Body durchzuschmuggeln (Backend strippt es eh)
- PasswordResetConfirm: Hinweis "Mind. 12 (Mitarbeiter: 25)"
- userApi.setPassword(id, password) neu
Live-verifiziert:
- POST /users/6/password "Hallo123!Test" (12) → 400 "mindestens 25"
- POST /users/6/password "MeinExtremLangesPW2026!Test" → 200,
Login mit neuem PW → success
- POST /customers/3/portal/password "Hallo123!Test" (12) → 200
- POST /users createUser mit 12-char-PW → 400 "mindestens 25"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -238,7 +238,9 @@ async function main() {
|
||||
const pick = (s: string) => s[Math.floor(Math.random() * s.length)];
|
||||
// mind. einen aus jeder Klasse + Rest zufällig
|
||||
const chars = [pick(upper), pick(lower), pick(digits), pick(special)];
|
||||
for (let i = chars.length; i < 16; i++) chars.push(pick(all));
|
||||
// 28 Zeichen → Komplexität + komfortable Marge über dem 25-Zeichen-
|
||||
// Mitarbeiter-Schwellwert (Pentest Runde 13).
|
||||
for (let i = chars.length; i < 28; i++) chars.push(pick(all));
|
||||
// Fisher-Yates Shuffle (sonst stehen die garantierten Klassen-Zeichen am Anfang)
|
||||
for (let i = chars.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
@@ -248,7 +250,7 @@ async function main() {
|
||||
}
|
||||
|
||||
const envPassword = process.env.SEED_ADMIN_PASSWORD;
|
||||
const adminPlainPassword = envPassword && envPassword.length >= 12
|
||||
const adminPlainPassword = envPassword && envPassword.length >= 25
|
||||
? envPassword
|
||||
: generateInitialPassword();
|
||||
const hashedPassword = await bcrypt.hash(adminPlainPassword, 12);
|
||||
@@ -269,9 +271,12 @@ async function main() {
|
||||
|
||||
console.log('========================================================');
|
||||
console.log(' Admin-User: admin@admin.com');
|
||||
if (envPassword) {
|
||||
if (envPassword && envPassword.length >= 25) {
|
||||
console.log(' Passwort: aus SEED_ADMIN_PASSWORD');
|
||||
} else {
|
||||
if (envPassword && envPassword.length < 25) {
|
||||
console.log(' ⚠️ SEED_ADMIN_PASSWORD < 25 Zeichen, wird ignoriert!');
|
||||
}
|
||||
console.log(` Initial-Passwort: ${adminPlainPassword}`);
|
||||
console.log(' ⚠️ Dieses Passwort wird hier EINMAL ausgegeben!');
|
||||
console.log(' Bitte sofort nach dem ersten Login ändern.');
|
||||
|
||||
Reference in New Issue
Block a user