Shuffle/e2e/tests/api/krit04-enumeration.spec.ts
cschlaefke f302c56904 test(auth): add Playwright project with api tests for KTO-01 (GoTrue, Mailpit, db helper)
Refs #38

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-03 10:29:18 +01:00

80 lines
3.9 KiB
TypeScript

import { expect, test } from '@playwright/test';
import { countUsers, profileByEmail, userByEmail } from '../../support/db';
import { GoTrueClient, randomEmail, randomPassword, validMetadata, waitMailInterval } from '../../support/gotrue';
import { countMails, expectMailCount, extractTokenHash, waitForMail } from '../../support/mailpit';
const gotrue = new GoTrueClient();
test.describe('KTO-01 Kriterium 4: Enumerationsschutz (api)', () => {
/**
* Regressionstest fuer AUTH-CFG-04 (MAILER_AUTOCONFIRM=false) UND AUTH-CFG-24 (SMS_AUTOCONFIRM=false).
* Mit SMS_AUTOCONFIRM=true (CLI-Standard, Self-Hosting-Vorlage) kaeme hier 422 user_already_exists.
*/
test('KTO-01 Kriterium 4: AUTH-CFG-04/-24 Signup mit bestaetigter Adresse -> 200 (nicht 422), identities leer, erfundener Nutzer, keine Mail, altes Passwort gilt', async () => {
const email = randomEmail();
const oldPassword = randomPassword();
const created = await gotrue.signUp(email, oldPassword);
const realId = created.body.id;
const { tokenHash } = extractTokenHash(await waitForMail(email));
expect((await gotrue.verify(tokenHash, 'email')).status).toBe(200);
expect(await countMails(email)).toBe(1);
await waitMailInterval();
const usersBefore = await countUsers();
const newPassword = randomPassword();
const again = await gotrue.signUp(email, newPassword, validMetadata({ display_name: 'Angreifer' }));
expect(again.status, 'nicht 422 user_already_exists (AUTH-CFG-24)').toBe(200);
expect(again.body.error_code).toBeUndefined();
expect(again.body.identities ?? []).toEqual([]);
expect(again.body.id).toBeTruthy();
expect(again.body.id).not.toBe(realId);
expect(await countUsers()).toBe(usersBefore);
// Keine (weitere) Mail an die Adresse: nach festem Fenster weiterhin nur die erste Bestaetigungsmail.
await expectMailCount(email, 1);
// Das urspruengliche Passwort gilt weiter, das neue nicht; das Profil bleibt unveraendert.
expect((await gotrue.signIn(email, oldPassword)).status).toBe(200);
const wrong = await gotrue.signIn(email, newPassword);
expect(wrong.status).toBe(400);
expect(wrong.body.error_code).toBe('invalid_credentials');
expect((await profileByEmail(email)).display_name).toBe('E2E Tester');
});
test('KTO-01 Kriterium 4: Signup mit unbestaetigter Adresse -> 200, Mail erneut an das bestehende Konto, Passwort und Profil unveraendert', async () => {
const email = randomEmail();
const oldPassword = randomPassword();
const first = await gotrue.signUp(email, oldPassword);
await waitForMail(email);
await waitMailInterval();
const newPassword = randomPassword();
const again = await gotrue.signUp(email, newPassword, validMetadata({ display_name: 'Angreifer' }));
expect(again.status).toBe(200);
expect(again.body.id).toBe(first.body.id);
// Die Bestaetigungsmail geht erneut an das bestehende Konto.
const second = await waitForMail(email, 2);
const { tokenHash } = extractTokenHash(second);
expect((await gotrue.verify(tokenHash, 'email')).status).toBe(200);
expect((await gotrue.signIn(email, oldPassword)).status).toBe(200);
expect((await gotrue.signIn(email, newPassword)).body.error_code).toBe('invalid_credentials');
expect((await profileByEmail(email)).display_name).toBe('E2E Tester');
expect((await userByEmail(email)).id).toBe(first.body.id);
});
test('KTO-01 Kriterium 4: Reset fuer unbekannte Adresse -> 200, keine Mail; fuer bekannte Adresse 200 mit Mail', async () => {
const unknown = randomEmail('unknown');
const res = await gotrue.recover(unknown);
expect(res.status).toBe(200);
await expectMailCount(unknown, 0);
const known = randomEmail();
await gotrue.createConfirmedUser(known, randomPassword());
const ok = await gotrue.recover(known);
expect(ok.status).toBe(200);
expect(ok.body).toEqual(res.body);
await waitForMail(known);
});
});