bilhej/frontend/e2e/auth-guards.spec.ts
Joakim Mörling 3532e4d486
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m9s
CI / E2E browser tests (pull_request) Successful in 1m55s
Add account settings dropdown and verified email change flow.
Replace the header "Byt lösenord" link with an Inställningar menu for
changing email or password. Email changes are two-step: request with
password, confirmation link to the new address, then password again on
confirm so a wrong inbox cannot take over the account.

- Backend: EmailChangeService, V10 email_change_tokens, confirm API
- Frontend: ChangeEmailPage, ConfirmEmailChangePage, header dropdown
- E2E: account-settings round-trips, Mailpit verification, wrong-password guard
- Flyway: V9 restore for dev DBs, CI migration checks, V10 for email tokens

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 14:33:06 +02:00

89 lines
3 KiB
TypeScript

import { test, expect } from '@playwright/test'
test.describe('Auth guards', () => {
test('redirects unauthenticated user from /compose to /logga-in', async ({
page,
}) => {
await page.goto('/compose')
await expect(page).toHaveURL(/\/logga-in\?redirect=\/compose/)
await expect(page.getByRole('heading', { name: 'Logga in' })).toBeVisible()
})
test('redirects unauthenticated user from /orders to /logga-in', async ({
page,
}) => {
await page.goto('/orders')
await expect(page).toHaveURL(/\/logga-in\?redirect=\/orders/)
await expect(page.getByRole('heading', { name: 'Logga in' })).toBeVisible()
})
test('redirects unauthenticated user from /admin to /logga-in', async ({
page,
}) => {
await page.goto('/admin')
await expect(page).toHaveURL(/\/logga-in\?redirect=\/admin/)
await expect(page.getByRole('heading', { name: 'Logga in' })).toBeVisible()
})
test('redirects unauthenticated user from /andra-losenord to /logga-in', async ({
page,
}) => {
await page.goto('/andra-losenord')
await expect(page).toHaveURL(/\/logga-in\?redirect=\/andra-losenord/)
await expect(page.getByRole('heading', { name: 'Logga in' })).toBeVisible()
})
test('redirects unauthenticated user from /andra-epost to /logga-in', async ({
page,
}) => {
await page.goto('/andra-epost')
await expect(page).toHaveURL(/\/logga-in\?redirect=\/andra-epost/)
await expect(page.getByRole('heading', { name: 'Logga in' })).toBeVisible()
})
test('redirects authenticated user from /logga-in to home', async ({
page,
}) => {
const jwt = makeJwt({ role: 'user' })
await page.goto('/')
await page.evaluate((token) => localStorage.setItem('auth_token', token), jwt)
await page.goto('/logga-in')
await expect(page).toHaveURL('/')
})
test('redirects authenticated user from /registrera to home', async ({
page,
}) => {
const jwt = makeJwt({ role: 'user' })
await page.goto('/')
await page.evaluate((token) => localStorage.setItem('auth_token', token), jwt)
await page.goto('/registrera')
await expect(page).toHaveURL('/')
})
test('redirects non-admin user from /admin to home', async ({ page }) => {
const jwt = makeJwt({ role: 'user' })
await page.goto('/')
await page.evaluate((token) => localStorage.setItem('auth_token', token), jwt)
await page.goto('/admin')
await expect(page).toHaveURL('/')
})
test('allows admin user to access /admin', async ({ page }) => {
const jwt = makeJwt({ role: 'admin' })
await page.goto('/')
await page.evaluate((token) => localStorage.setItem('auth_token', token), jwt)
await page.goto('/admin')
await expect(page).toHaveURL('/admin')
await expect(
page.getByRole('heading', { name: 'Administration' }),
).toBeVisible()
})
})
function makeJwt(payload: Record<string, unknown>): string {
const header = btoa(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))
const body = btoa(JSON.stringify(payload))
const signature = 'test-sig'
return `${header}.${body}.${signature}`
}