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); }); });