learning_ai_common_plat/dashboards/admin-web/e2e/smartauth-step-up.spec.ts
saravanakumardb1 0c4e53a0ed feat(auth): Phase 6 — enterprise SAML/OIDC, magic link, HIBP, E2E specs
6A: Enterprise IdP CRUD, SAML callback, OIDC callback, email domain lookup
6B: Magic link send/verify (15min TTL, anti-enumeration), HIBP breach check
6D: 3 new E2E specs (account-linking, step-up, enterprise) — total 8 SmartAuth specs
- All 53 auth tests passing
2026-03-12 15:25:28 -07:00

86 lines
2.8 KiB
TypeScript

/**
* SmartAuth E2E — Step-Up Authentication
* Tests re-verification flows for sensitive operations.
*/
import { test, expect } from '@playwright/test';
test.describe('SmartAuth: Step-Up Auth', () => {
test.beforeEach(async ({ page }) => {
await page.route('**/api/auth/me', route =>
route.fulfill({
status: 200,
body: JSON.stringify({
id: 'usr_test',
email: 'admin@acme.com',
role: 'admin',
displayName: 'Test Admin',
mfaEnabled: true,
mfaMethods: ['totp'],
}),
})
);
});
test('should require step-up for sensitive operations', async ({ page }) => {
// Mock a sensitive endpoint that returns 403 without step-up
await page.route('**/api/auth/mfa/totp', route => {
const method = route.request().method();
if (method === 'DELETE') {
route.fulfill({
status: 403,
body: JSON.stringify({ error: 'Step-up authentication required' }),
});
} else {
route.fulfill({ status: 200, body: '{}' });
}
});
await page.goto('/settings/security');
// Look for step-up prompt or re-verify dialog
const disableButton = page.getByRole('button', { name: /disable mfa/i });
if (await disableButton.isVisible()) {
await disableButton.click();
await expect(page.getByText(/step-up|re-verify|confirm your identity/i)).toBeVisible();
}
});
test('should complete step-up with password', async ({ page }) => {
await page.route('**/api/auth/step-up', route =>
route.fulfill({
status: 200,
body: JSON.stringify({ stepUpToken: 'step_test_token', expiresIn: 300 }),
})
);
await page.goto('/settings/security');
// Verify step-up flow returns token
const response = await page.evaluate(async () => {
const res = await fetch('/api/auth/step-up', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ method: 'password', credential: 'test123' }),
});
return res.json();
});
expect(response).toHaveProperty('stepUpToken');
});
test('should complete step-up with TOTP', async ({ page }) => {
await page.route('**/api/auth/step-up', route =>
route.fulfill({
status: 200,
body: JSON.stringify({ stepUpToken: 'step_totp_token', expiresIn: 300 }),
})
);
await page.goto('/settings/security');
const response = await page.evaluate(async () => {
const res = await fetch('/api/auth/step-up', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ method: 'totp', credential: '123456' }),
});
return res.json();
});
expect(response).toHaveProperty('stepUpToken');
});
});