diff --git a/web/e2e/helpers/auth-fixtures.ts b/web/e2e/helpers/auth-fixtures.ts index 31a9fb4a..fc89c8a1 100644 --- a/web/e2e/helpers/auth-fixtures.ts +++ b/web/e2e/helpers/auth-fixtures.ts @@ -5,3 +5,12 @@ export async function setEnglishLocale(page: Page) { window.localStorage.setItem('i18nextLng', 'en') }) } + +export async function setUniqueClientIp(page: Page, seed: string) { + const suffix = Date.now() + Math.floor(Math.random() * 1000) + const thirdOctet = seed.split('').reduce((sum, char) => sum + char.charCodeAt(0), 0) % 250 + const fourthOctet = suffix % 250 + await page.context().setExtraHTTPHeaders({ + 'X-Forwarded-For': `10.0.${thirdOctet}.${fourthOctet}`, + }) +} diff --git a/web/e2e/password-reset.spec.ts b/web/e2e/password-reset.spec.ts index dc86a854..a37efcf5 100644 --- a/web/e2e/password-reset.spec.ts +++ b/web/e2e/password-reset.spec.ts @@ -1,25 +1,18 @@ import { expect, test } from '@playwright/test' -import { setEnglishLocale } from './helpers/auth-fixtures' +import { setEnglishLocale, setUniqueClientIp } from './helpers/auth-fixtures' test.describe('Password Reset (Real API)', () => { function uniqueResetEmail(seed: string) { return `nonexistent_${seed}_${Date.now()}@example.com` } - function forwardedIp(seed: string) { - const hash = Array.from(seed).reduce((value, char) => value + char.charCodeAt(0), 0) - return `198.51.${(hash % 200) + 1}.${(Date.now() % 200) + 1}` - } - test.beforeEach(async ({ page }) => { await setEnglishLocale(page) }) test('sends verification code from reset-password page', async ({ page }) => { const email = uniqueResetEmail('request') - await page.context().setExtraHTTPHeaders({ - 'X-Forwarded-For': forwardedIp('request'), - }) + await setUniqueClientIp(page, 'password-reset-request') await page.goto('/reset-password') @@ -32,9 +25,7 @@ test.describe('Password Reset (Real API)', () => { test('shows backend validation error for an invalid reset code', async ({ page }) => { const email = uniqueResetEmail('invalid-code') - await page.context().setExtraHTTPHeaders({ - 'X-Forwarded-For': forwardedIp('invalid-code'), - }) + await setUniqueClientIp(page, 'password-reset-invalid-code') await page.goto('/reset-password')