61 lines
2.9 KiB
TypeScript
61 lines
2.9 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
import { GoTrueClient, randomEmail, randomPassword } from '../../support/gotrue';
|
|
import { extractTokenHash, waitForMail } from '../../support/mailpit';
|
|
import { enableSemantics, expectSignedIn, expectSignedInViaLoginRedirect, login, readAuthStorage, shiftBrowserClock } from '../../support/web';
|
|
|
|
const gotrue = new GoTrueClient();
|
|
|
|
test.describe('KTO-01 Kriterium 9 (web): Passwort-Reset beendet andere Sitzungen', () => {
|
|
test('KTO-01 Kriterium 9: zweiter Browser-Kontext ist nach dem Reset und dem naechsten (erzwungenen) Refresh abgemeldet', async ({
|
|
page,
|
|
browser,
|
|
}) => {
|
|
const email = randomEmail();
|
|
const oldPassword = randomPassword();
|
|
await gotrue.createConfirmedUser(email, oldPassword);
|
|
|
|
// Sitzung B: ein zweites Geraet in eigenem Kontext.
|
|
await login(page, email, oldPassword);
|
|
await expectSignedIn(page);
|
|
|
|
// Reset ueber Sitzung A (API): neues Passwort setzen beendet alle anderen Sitzungen.
|
|
await gotrue.recover(email);
|
|
const { tokenHash } = extractTokenHash(await waitForMail(email));
|
|
const recovery = await gotrue.verify(tokenHash, 'recovery');
|
|
const update = await gotrue.updateUser(recovery.body.access_token, { password: randomPassword() });
|
|
expect(update.status).toBe(200);
|
|
|
|
// Der Access-Token laeuft erst nach jwt_expiry (AUTH-CFG-14, bis 60 min, F1) ab: Der Test
|
|
// erzwingt den Refresh, indem er die Browser-Uhr um 2 h vorstellt.
|
|
await shiftBrowserClock(page, 2 * 60 * 60 * 1000);
|
|
await page.reload();
|
|
await enableSemantics(page);
|
|
// Der Refresh scheitert (refresh_token_not_found): supabase_flutter loescht die Sitzung.
|
|
await expect.poll(async () => Object.keys(await readAuthStorage(page)), { timeout: 15_000 }).toEqual([]);
|
|
// Abgemeldet: /login leitet nicht mehr auf die Startseite (Gegenprobe zu Krit. 5).
|
|
await page.goto('/login');
|
|
await enableSemantics(page);
|
|
await page.waitForTimeout(1_000);
|
|
await expect(page).toHaveURL(/\/login$/);
|
|
await expect(page.getByRole('button', { name: 'Sign in', exact: true })).toBeVisible();
|
|
});
|
|
|
|
test('KTO-01 Kriterium 9: Gegenprobe ohne Reset und mit abgelaufenem Access-Token bleibt die Sitzung bestehen (Refresh klappt)', async ({
|
|
page,
|
|
}) => {
|
|
const email = randomEmail();
|
|
const password = randomPassword();
|
|
await gotrue.createConfirmedUser(email, password);
|
|
await login(page, email, password);
|
|
await expectSignedIn(page);
|
|
|
|
await shiftBrowserClock(page, 2 * 60 * 60 * 1000);
|
|
const before = JSON.parse(Object.values(await readAuthStorage(page))[0]).access_token;
|
|
await page.reload();
|
|
await expectSignedInViaLoginRedirect(page);
|
|
// Der Refresh lief wirklich: neues Access-Token im Storage.
|
|
await expect
|
|
.poll(async () => JSON.parse(Object.values(await readAuthStorage(page))[0] ?? '{}').access_token)
|
|
.not.toBe(before);
|
|
});
|
|
});
|