Files
Webklar-Kundenbereich/test/customerPassword.test.js
T

63 lines
4.0 KiB
JavaScript

import { test } from 'node:test'
import assert from 'node:assert/strict'
// Vor dem Import von config.js setzen: Appwrite unerreichbar (Port 9), damit kein Test ins Netz geht
process.env.APPWRITE_ENDPOINT = 'http://127.0.0.1:9/v1'
process.env.APPWRITE_API_KEY = 'test'
const { attemptState, newPasswordProblem, recordAttempt } = await import('../server/services/customerPassword.js')
const { forgetPasswordVersion, isSessionPasswordCurrent, rememberPasswordVersion } = await import('../server/services/passwordVersion.js')
test('Neues Passwort: Laenge in Zeichen, Grenze von Appwrite in Byte', () => {
assert.equal(newPasswordProblem('alt-alt-alt', ''), 'Bitte gib ein neues Passwort ein.')
assert.match(newPasswordProblem('alt-alt-alt', '1234567'), /mindestens 8 Zeichen/)
assert.equal(newPasswordProblem('alt-alt-alt', '1234567ä'), '')
// Emoji zaehlen als ein Zeichen (nicht als zwei UTF-16-Einheiten)
assert.match(newPasswordProblem('alt-alt-alt', '😀'.repeat(7)), /mindestens 8 Zeichen/)
assert.equal(newPasswordProblem('alt-alt-alt', '😀'.repeat(8)), '')
assert.equal(newPasswordProblem('alt-alt-alt', 'x'.repeat(256)), '')
assert.match(newPasswordProblem('alt-alt-alt', 'x'.repeat(257)), /zu lang/)
assert.equal(newPasswordProblem('alt-alt-alt', 'ü'.repeat(128)), '')
assert.match(newPasswordProblem('alt-alt-alt', 'ü'.repeat(129)), /zu lang/)
})
test('Neues Passwort: nicht leer, nicht das alte, nicht die E-Mail', () => {
assert.match(newPasswordProblem('alt-alt-alt', ' '.repeat(10)), /Leerzeichen/)
assert.match(newPasswordProblem('Altes-Passwort', 'Altes-Passwort'), /unterscheiden/)
assert.match(newPasswordProblem('alt-alt-alt', ' Kunde@Beispiel.de ', 'kunde@beispiel.de'), /E-Mail-Adresse/)
assert.equal(newPasswordProblem('alt-alt-alt', 'kunde@beispiel.de!', 'kunde@beispiel.de'), '')
assert.equal(newPasswordProblem('alt-alt-alt', 'Ein langer Satz, den nur ich kenne'), '')
})
test('Versuche: 5 je Stunde und Kunde, danach Sperre bis der erste eine Stunde alt ist', () => {
const t0 = Date.parse('2026-09-27T10:00:00Z')
const min = 60 * 1000
assert.deepEqual(attemptState('k1', t0), { left: 5, blockedFor: 0 })
for (let i = 0; i < 4; i++) recordAttempt('k1', t0 + i * min)
assert.deepEqual(attemptState('k1', t0 + 4 * min), { left: 1, blockedFor: 0 })
recordAttempt('k1', t0 + 4 * min)
assert.deepEqual(attemptState('k1', t0 + 5 * min), { left: 0, blockedFor: 55 * 60 })
// Nach einer Stunde ist der erste Versuch verfallen: wieder einer frei
assert.deepEqual(attemptState('k1', t0 + 60 * min), { left: 1, blockedFor: 0 })
assert.deepEqual(attemptState('k1', t0 + 65 * min), { left: 5, blockedFor: 0 })
// Andere Kunden sind nicht betroffen
assert.deepEqual(attemptState('k2', t0 + 5 * min), { left: 5, blockedFor: 0 })
})
test('Sessions: nach Passwortaenderung ungueltig, alte ohne Stand und Admins bleiben', async () => {
rememberPasswordVersion('u1', '2026-09-27T10:00:00.000+00:00')
assert.equal(await isSessionPasswordCurrent({ appwriteUserId: 'u1', customerId: 'c1', pwv: '2026-09-27T10:00:00.000+00:00' }), true)
assert.equal(await isSessionPasswordCurrent({ appwriteUserId: 'u1', customerId: 'c1', pwv: '2026-09-01T08:00:00.000+00:00' }), false)
// Session von vor dieser Pruefung (ohne pwv) laeuft normal aus
assert.equal(await isSessionPasswordCurrent({ appwriteUserId: 'u1', customerId: 'c1' }), true)
// Kundenansicht: appwriteUserId ist die des Mitarbeiters
assert.equal(await isSessionPasswordCurrent({ role: 'admin', viewAs: true, appwriteUserId: 'u1', customerId: 'c1', pwv: 'x' }), true)
// Konto ohne Passwort (geleert): keine Session gilt mehr
rememberPasswordVersion('u2', '')
assert.equal(await isSessionPasswordCurrent({ appwriteUserId: 'u2', customerId: 'c2', pwv: '2026-09-27T10:00:00.000+00:00' }), false)
})
test('Sessions: ist Appwrite nicht erreichbar, bleibt man angemeldet', async () => {
forgetPasswordVersion('u3')
assert.equal(await isSessionPasswordCurrent({ appwriteUserId: 'u3', customerId: 'c3', pwv: 'irgendwas' }), true)
})