Files
fluxer/fluxer_api/src/api/auth/tests/IPAuthFlow.test.ts
T

101 lines
2.9 KiB
TypeScript

// SPDX-License-Identifier: AGPL-3.0-or-later
import {afterAll, beforeAll, beforeEach, describe, expect, it} from 'vitest';
import type {ApiTestHarness} from '../../test/ApiTestHarness';
import {createBuilderWithoutAuth} from '../../test/TestRequestBuilder';
import {
clearTestEmails,
createAuthHarness,
createUniqueEmail,
createUniqueUsername,
findLastTestEmail,
listTestEmails,
registerUser,
} from './AuthTestUtils';
describe('Auth IP Authorization Flow', () => {
let harness: ApiTestHarness;
beforeAll(async () => {
harness = await createAuthHarness();
});
beforeEach(async () => {
await harness.reset();
await clearTestEmails(harness);
});
afterAll(async () => {
await harness?.shutdown();
});
it('validates the complete IP authorization flow', async () => {
const email = createUniqueEmail('ip-auth-flow');
const password = 'a-strong-password';
const reg = await registerUser(harness, {
email,
username: createUniqueUsername('ipflow'),
global_name: 'IP Auth Flow User',
password,
date_of_birth: '2000-01-01',
consent: true,
});
await clearTestEmails(harness);
const newIP = '10.20.30.40';
const ipAuthResp = await createBuilderWithoutAuth<{
code?: string;
ticket?: string;
ip_authorization_required?: boolean;
email?: string;
resend_available_in?: number;
message?: string;
}>(harness)
.post('/auth/login')
.body({email, password})
.header('x-forwarded-for', newIP)
.expect(403)
.execute();
expect(ipAuthResp.ip_authorization_required).toBe(true);
expect(ipAuthResp.ticket).toBeTruthy();
expect(ipAuthResp.email).toBe(email);
const emails = await listTestEmails(harness, {recipient: email});
const ipAuthEmail = findLastTestEmail(emails, 'ip_authorization');
expect(ipAuthEmail).not.toBeNull();
const authToken = ipAuthEmail?.metadata['token'];
expect(authToken).toBeTruthy();
await createBuilderWithoutAuth(harness)
.post('/auth/authorize-ip')
.body({token: authToken})
.header('x-forwarded-for', newIP)
.expect(204)
.execute();
const loginResp = await createBuilderWithoutAuth<{
token?: string;
user_id?: string;
}>(harness)
.post('/auth/login')
.body({email, password})
.header('x-forwarded-for', newIP)
.execute();
expect(loginResp.token).toBeTruthy();
expect(loginResp.user_id).toBe(reg.user_id);
});
it('validates that login from a known IP does not trigger IP authorization', async () => {
const email = createUniqueEmail('ip-known');
const password = 'a-strong-password';
const reg = await registerUser(harness, {
email,
username: createUniqueUsername('ipknown'),
global_name: 'IP Known User',
password,
date_of_birth: '2000-01-01',
consent: true,
});
const loginResp = await createBuilderWithoutAuth<{
token?: string;
user_id?: string;
}>(harness)
.post('/auth/login')
.body({email, password})
.execute();
expect(loginResp.token).toBeTruthy();
expect(loginResp.user_id).toBe(reg.user_id);
});
});