106 lines
4.8 KiB
TypeScript
106 lines
4.8 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
import { authConfig, errorCodes } from '../../support/auth-config';
|
|
import { expireConfirmationLink, expireRecoveryLink } from '../../support/db';
|
|
import { GoTrueClient, randomEmail, randomPassword, waitMailInterval } from '../../support/gotrue';
|
|
import { expectMailCount, extractTokenHash, waitForMail } from '../../support/mailpit';
|
|
|
|
const gotrue = new GoTrueClient();
|
|
|
|
async function confirmedUser() {
|
|
const email = randomEmail();
|
|
const password = randomPassword();
|
|
const created = await gotrue.createConfirmedUser(email, password);
|
|
expect(created.status).toBe(200);
|
|
return { email, password };
|
|
}
|
|
|
|
test.describe('KTO-01 Kriterium 8: Passwort-Reset-Link (api)', () => {
|
|
test('KTO-01 Kriterium 8: Reset anfordern -> Mail mit type=recovery -> einloesen ok -> zweites Einloesen 403 otp_expired', async () => {
|
|
const { email } = await confirmedUser();
|
|
expect((await gotrue.recover(email)).status).toBe(200);
|
|
const { tokenHash, type } = extractTokenHash(await waitForMail(email));
|
|
expect(type).toBe('recovery');
|
|
|
|
const first = await gotrue.verify(tokenHash, 'recovery');
|
|
expect(first.status).toBe(200);
|
|
expect(first.body.access_token).toBeTruthy();
|
|
|
|
const second = await gotrue.verify(tokenHash, 'recovery');
|
|
expect(second.status).toBe(403);
|
|
expect(second.body.error_code).toBe(errorCodes.otpExpired);
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: neue Reset-Anforderung ersetzt den alten Link', async () => {
|
|
const { email } = await confirmedUser();
|
|
await gotrue.recover(email);
|
|
const oldLink = extractTokenHash(await waitForMail(email));
|
|
await waitMailInterval();
|
|
await gotrue.recover(email);
|
|
const newLink = extractTokenHash(await waitForMail(email, 2));
|
|
expect(newLink.tokenHash).not.toBe(oldLink.tokenHash);
|
|
|
|
const old = await gotrue.verify(oldLink.tokenHash, 'recovery');
|
|
expect(old.status).toBe(403);
|
|
expect(old.body.error_code).toBe(errorCodes.otpExpired);
|
|
expect((await gotrue.verify(newLink.tokenHash, 'recovery')).status).toBe(200);
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: AUTH-CFG-07 Reset-Link ist nach 1 h + 1 s abgelaufen (recovery_sent_at zurueckgesetzt)', async () => {
|
|
const { email } = await confirmedUser();
|
|
await gotrue.recover(email);
|
|
const { tokenHash } = extractTokenHash(await waitForMail(email));
|
|
await expireRecoveryLink(email);
|
|
|
|
const res = await gotrue.verify(tokenHash, 'recovery');
|
|
expect(res.status).toBe(403);
|
|
expect(res.body.error_code).toBe(errorCodes.otpExpired);
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: AUTH-CFG-07 Grenze: Reset-Link kurz vor Ablauf ist noch gueltig', async () => {
|
|
const { email } = await confirmedUser();
|
|
await gotrue.recover(email);
|
|
const { tokenHash } = extractTokenHash(await waitForMail(email));
|
|
await expireRecoveryLink(email, authConfig.otpExpirySeconds - 60);
|
|
expect((await gotrue.verify(tokenHash, 'recovery')).status).toBe(200);
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: AUTH-CFG-07 Bestaetigungslink ist nach 1 h + 1 s abgelaufen (confirmation_sent_at zurueckgesetzt)', async () => {
|
|
const email = randomEmail();
|
|
const password = randomPassword();
|
|
await gotrue.signUp(email, password);
|
|
const { tokenHash } = extractTokenHash(await waitForMail(email));
|
|
await expireConfirmationLink(email);
|
|
|
|
const res = await gotrue.verify(tokenHash, 'email');
|
|
expect(res.status).toBe(403);
|
|
expect(res.body.error_code).toBe(errorCodes.otpExpired);
|
|
// Konto bleibt unbestaetigt.
|
|
expect((await gotrue.signIn(email, password)).body.error_code).toBe(errorCodes.emailNotConfirmed);
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: Bestaetigungslink ist einmalig', async () => {
|
|
const email = randomEmail();
|
|
await gotrue.signUp(email, randomPassword());
|
|
const { tokenHash } = extractTokenHash(await waitForMail(email));
|
|
expect((await gotrue.verify(tokenHash, 'email')).status).toBe(200);
|
|
const again = await gotrue.verify(tokenHash, 'email');
|
|
expect(again.status).toBe(403);
|
|
expect(again.body.error_code).toBe(errorCodes.otpExpired);
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: Reset fuer unbekannte Adresse -> 200, keine Mail', async () => {
|
|
const unknown = randomEmail('unknown');
|
|
expect((await gotrue.recover(unknown)).status).toBe(200);
|
|
await expectMailCount(unknown, 0);
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: nach dem Setzen des neuen Passworts ist der Reset-Link verbraucht', async () => {
|
|
const { email } = await confirmedUser();
|
|
await gotrue.recover(email);
|
|
const { tokenHash } = extractTokenHash(await waitForMail(email));
|
|
const session = await gotrue.verify(tokenHash, 'recovery');
|
|
const update = await gotrue.updateUser(session.body.access_token, { password: randomPassword() });
|
|
expect(update.status).toBe(200);
|
|
expect((await gotrue.verify(tokenHash, 'recovery')).body.error_code).toBe(errorCodes.otpExpired);
|
|
});
|
|
});
|