import {popEmail} from "./_mail_server"; import supertest from "supertest"; import {AppSupplier} from "./_app"; import TestApp from "../src/TestApp"; import Controller from "../src/Controller"; import CsrfProtectionComponent from "../src/components/CsrfProtectionComponent"; import AuthComponent from "../src/auth/AuthComponent"; import Migration, {MigrationType} from "../src/db/Migration"; import AddNameToUsersMigration from "../src/auth/migrations/AddNameToUsersMigration"; import AddApprovedFieldToUsersTableMigration from "../src/auth/migrations/AddApprovedFieldToUsersTableMigration"; import PasswordAuthProof from "../src/auth/password/PasswordAuthProof"; import MagicLink from "../src/auth/models/MagicLink"; export async function followMagicLinkFromMail( agent: supertest.SuperTest, cookies: string[], expectedRedirectUrl: string = '/', ): Promise { const mail: Record | null = await popEmail(); expect(mail).not.toBeNull(); const query = (mail?.text as string).split('/magic/link?')[1].split('\n')[0]; expect(query).toBeDefined(); await agent.get('/magic/link?' + query) .expect(200); await agent.get('/magic/lobby') .set('Cookie', cookies) .expect(302) .expect('Location', expectedRedirectUrl); } export async function testLogout( agent: supertest.SuperTest, cookies: string[], csrf: string, ): Promise { // Authenticated await agent.get('/is-auth').set('Cookie', cookies).expect(200); // Logout await agent.post('/auth/logout') .set('Cookie', cookies) .send({csrf: csrf}) .expect(302); // Not authenticated await agent.get('/is-auth').set('Cookie', cookies).expect(401); } export function authAppProvider(withUsername: boolean = true, approvalMode: boolean = false): AppSupplier { return async (addr, port) => { return new class extends TestApp { protected async init(): Promise { this.use(new class extends Controller { public routes(): void { this.get('/', (req, res) => { res.render('home'); }, 'home'); this.get('/csrf', (req, res) => { res.send(CsrfProtectionComponent.getCsrfToken(req.getSession())); }, 'csrf'); this.get('/is-auth', async (req, res) => { const proofs = await this.getApp().as(AuthComponent).getAuthGuard().getProofs(req); if (proofs.length > 0) res.sendStatus(200); else res.sendStatus(401); }, 'is-auth'); this.get('/has-any-password-auth-proof', async (req, res) => { const proof = await PasswordAuthProof.getProofForSession(req.getSession()); if (proof) res.sendStatus(200); else res.sendStatus(404); }, 'is-auth'); this.get('/has-any-magic-link', async (req, res) => { const proofs = await MagicLink.select() .where('session_id', req.getSession().id) .get(); if (proofs.length > 0) res.sendStatus(200); else res.sendStatus(404); }, 'is-auth'); } }()); await super.init(); } protected getMigrations(): MigrationType[] { let migrations = withUsername ? super.getMigrations() : super.getMigrations().filter(m => m !== AddNameToUsersMigration); migrations = approvalMode ? [...migrations, AddApprovedFieldToUsersTableMigration] : migrations; return migrations; } }(addr, port, true); }; }