Admin-Modus: Verwaltung aller Matches unter /admin

Anmeldung mit ADMIN_PASSWORD (12 h, Sitzung nur im Speicher, Sperre nach
5 Fehlversuchen pro Minute). Alle Matches mit Codes, Servern, Spielern,
Veto und Verlauf. Aktionen: Veto starten bzw. Schritte für beide Teams,
Warmup beenden, nächste Map, Server stoppen/neu starten, abschließen,
abbrechen, Spieler entfernen, Codes erneuern, Match löschen.
Ohne ADMIN_PASSWORD ist der Admin-Modus komplett aus.
This commit is contained in:
mregosar committed 2026-10-25 23:16:44 +01:00
1 parent 30ec5359b1
commit 46d1954a6d
8 files changed
+446

No files matched your search

+46
View File
@@ -377,6 +377,52 @@ test('Stream-Übersicht aller Matches: Inhalte, keine Geheimnisse, optionaler Sc
}
});
test('Admin-Modus: Anmeldung, Verwaltung aller Matches, Sperre ohne Anmeldung', async () => {
const { app, call, close } = await setup({ adminPassword: 'Admin123' });
try {
const { id } = (await call('POST', '/matches', {
body: { teamA: 'Alpha', teamB: 'Bravo', mode: 'wingman', format: 'bo1' },
})).body;
const adminListed = (await call('GET', '/admin/matches')).body; // ohne Anmeldung
assert.equal(adminListed.error, 'Admin-Anmeldung erforderlich');
assert.equal((await call('POST', '/admin/login', { body: { password: 'falsch' } })).status, 401);
const login = (await call('POST', '/admin/login', { body: { password: 'Admin123' } })).body;
const admin = { token: login.token };
assert.ok(login.token);
const list = (await call('GET', '/admin/matches', admin)).body.matches;
const mine = list.find((m) => m.id === id);
assert.ok(mine, 'alle Matches sichtbar, nicht nur die eigenen');
assert.ok(mine.organizer.codes.A, 'Codes sichtbar');
// Ein Match abbrechen wie ein Admin
assert.equal((await call('POST', `/admin/matches/${id}/cancel`, { ...admin, body: {} })).status, 200);
assert.equal(app.service.getMatch(id).status, 'cancelled');
// Endgültig löschen
assert.equal((await call('DELETE', `/admin/matches/${id}`, admin)).status, 200);
assert.equal((await call('GET', `/matches/${id}`)).status, 404);
// Abmelden: Token ist danach ungültig
await call('POST', '/admin/logout', admin);
assert.equal((await call('GET', '/admin/session', admin)).status, 401);
} finally {
await close();
}
});
test('Admin-Modus ohne ADMIN_PASSWORD ist komplett aus', async () => {
const { call, close } = await setup({ adminPassword: '' });
try {
const res = await call('POST', '/admin/login', { body: { password: 'x' } });
assert.equal(res.status, 404);
assert.equal(res.body.code, 'admin_disabled');
} finally {
await close();
}
});
test('Spieler verlassen die Lobby, Captain geht über', async () => {
const { call, close } = await setup();
try {