Files
ferdi2goandClaude Fable 5.1 33a8adef0e Bearbeitung hinter ein Passwort legen, Ansehen für das Team freigeben
Mit EDIT_PASSWORD sehen Besucher nur den Kalender: keine E-Mails, Notizen,
Abwesenheiten oder Nextcloud-Details, keine schreibenden Aktionen. Anmelden
in der Kopfzeile setzt ein signiertes Cookie für 30 Tage; nach fünf
Fehlversuchen wartet der Server eine Minute. Ohne EDIT_PASSWORD bleibt
alles offen wie bisher.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 12:36:23 +00:00

52 lines
1.9 KiB
JavaScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { createAuth, readCookie, cookieHeader, COOKIE_NAME } from '../server/auth.js';
test('ohne Passwort ist der Schutz aus', () => {
const a = createAuth({ password: '', secret: 's' });
assert.equal(a.enabled, false);
assert.equal(a.checkPassword(''), false);
});
test('Passwortprüfung und signierte Token', () => {
let t = 1_000_000;
const a = createAuth({ password: 'geheim', secret: 'schluessel', now: () => t });
assert.ok(a.enabled);
assert.ok(a.checkPassword('geheim'));
assert.ok(!a.checkPassword('Geheim'));
assert.ok(!a.checkPassword(undefined));
const token = a.issue();
assert.ok(a.verify(token));
assert.ok(!a.verify(token + 'x'), 'manipulierte Signatur');
assert.ok(!a.verify('123.abc'));
assert.ok(!a.verify(''));
const other = createAuth({ password: 'geheim', secret: 'anderer', now: () => t });
assert.ok(!other.verify(token), 'anderer Schlüssel');
t += a.ttlMs + 1;
assert.ok(!a.verify(token), 'abgelaufen');
});
test('Bremse nach fünf Fehlversuchen', () => {
let t = 0;
const a = createAuth({ password: 'x', secret: 's', now: () => t });
for (let i = 0; i < 4; i += 1) a.noteFailure('1.2.3.4');
assert.equal(a.blockedFor('1.2.3.4'), 0);
a.noteFailure('1.2.3.4');
assert.ok(a.blockedFor('1.2.3.4') > 0);
assert.equal(a.blockedFor('5.6.7.8'), 0);
t += 61_000;
assert.equal(a.blockedFor('1.2.3.4'), 0);
a.noteFailure('1.2.3.4');
a.noteSuccess('1.2.3.4');
assert.equal(a.blockedFor('1.2.3.4'), 0);
});
test('Cookie lesen und schreiben', () => {
const header = cookieHeader('abc.def', { secure: true });
assert.ok(header.startsWith(`${COOKIE_NAME}=abc.def; Path=/; HttpOnly; SameSite=Lax; Max-Age=`));
assert.ok(header.endsWith('; Secure'));
assert.equal(readCookie(`foo=1; ${COOKIE_NAME}=abc.def; bar=2`), 'abc.def');
assert.equal(readCookie('foo=1'), null);
assert.equal(readCookie(undefined), null);
});