import { expect, test } from '@playwright/test'; import { env, errorCodes } from '../../support/auth-config'; import { GoTrueClient, randomEmail, randomPassword } from '../../support/gotrue'; import { extractTokenHash, waitForMail } from '../../support/mailpit'; const gotrue = new GoTrueClient(); async function resetSession(email: string) { await gotrue.recover(email); const { tokenHash } = extractTokenHash(await waitForMail(email)); const res = await gotrue.verify(tokenHash, 'recovery'); expect(res.status).toBe(200); return res.body.access_token as string; } test.describe('KTO-01 Kriterium 9: Passwort aendern beendet andere Sitzungen (api)', () => { test('KTO-01 Kriterium 9: nach Reset sind die Refresh-Tokens anderer Sitzungen ungueltig, die Reset-Sitzung bleibt', async () => { const email = randomEmail(); const oldPassword = randomPassword(); const newPassword = randomPassword(); await gotrue.createConfirmedUser(email, oldPassword); const a = (await gotrue.signIn(email, oldPassword)).body; const b = (await gotrue.signIn(email, oldPassword)).body; expect(a.refresh_token).not.toBe(b.refresh_token); const recoveryToken = await resetSession(email); const update = await gotrue.updateUser(recoveryToken, { password: newPassword }); expect(update.status).toBe(200); for (const [name, session] of [['A', a], ['B', b]] as const) { const refreshed = await gotrue.refresh(session.refresh_token); expect(refreshed.status, `Sitzung ${name}`).toBeGreaterThanOrEqual(400); expect(['refresh_token_not_found', 'session_not_found']).toContain( refreshed.body.error_code, ); } // Neues Passwort gilt, altes nicht. expect((await gotrue.signIn(email, newPassword)).status).toBe(200); expect((await gotrue.signIn(email, oldPassword)).body.error_code).toBe(errorCodes.invalidCredentials); }); test('KTO-01 Kriterium 9 / R8: GoTrue /user lehnt das Access-Token der beendeten Sitzung ab (PostgREST nicht: bis zu 60 min, F1)', async () => { const email = randomEmail(); const oldPassword = randomPassword(); await gotrue.createConfirmedUser(email, oldPassword); const a = (await gotrue.signIn(email, oldPassword)).body; const recoveryToken = await resetSession(email); await gotrue.updateUser(recoveryToken, { password: randomPassword() }); const user = await gotrue.getUser(a.access_token); expect([401, 403]).toContain(user.status); // Dokumentiert das akzeptierte Restrisiko R8 (AUTH-CFG-14): PostgREST prueft keine Sitzungen. const rest = await fetch(`${env.supabaseUrl}/rest/v1/profiles?select=id`, { headers: { apikey: env.anonKey, authorization: `Bearer ${a.access_token}` }, }); expect(rest.status).toBe(200); }); test('KTO-01 Kriterium 9: gleiches Passwort -> 422 same_password, zu kurzes -> 422 weak_password', async () => { const email = randomEmail(); const password = randomPassword(); await gotrue.createConfirmedUser(email, password); const token = await resetSession(email); const same = await gotrue.updateUser(token, { password }); expect(same.status).toBe(422); expect(same.body.error_code).toBe(errorCodes.samePassword); const weak = await gotrue.updateUser(token, { password: 'kurz' }); expect(weak.status).toBe(422); expect(weak.body.error_code).toBe(errorCodes.weakPassword); }); });