import TestApp from "../src/TestApp"; import useApp from "./_app"; import Controller from "../src/Controller"; import supertest from "supertest"; import CsrfProtectionComponent from "../src/components/CsrfProtectionComponent"; import UserPasswordComponent from "../src/auth/password/UserPasswordComponent"; import {popEmail} from "./_mail_server"; import AuthComponent from "../src/auth/AuthComponent"; import Migration, {MigrationType} from "../src/db/Migration"; import AddNameToUsersMigration from "../src/auth/migrations/AddNameToUsersMigration"; import {followMagicLinkFromMail, testLogout} from "./_authentication_common"; import UserEmail from "../src/auth/models/UserEmail"; let app: TestApp; useApp(async (addr, port) => { return app = 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'); } }()); await super.init(); } protected getMigrations(): MigrationType[] { return super.getMigrations().filter(m => m !== AddNameToUsersMigration); } }(addr, port); }); let agent: supertest.SuperTest; beforeAll(() => { agent = supertest(app.getExpressApp()); }); describe('Register with username and password (password)', () => { test('Must be disabled', async () => { const res = await agent.get('/csrf').expect(200); const cookies = res.get('Set-Cookie'); const csrf = res.text; // Register user await agent.post('/auth/register') .set('Cookie', cookies) .send({ csrf: csrf, auth_method: 'password', identifier: 'entrapta', password: 'darla_is_cute', password_confirmation: 'darla_is_cute', terms: 'on', }) .expect(500); }); }); describe('Register with email (magic_link)', () => { test('General case', async () => { const res = await agent.get('/csrf').expect(200); const cookies = res.get('Set-Cookie'); const csrf = res.text; await agent.post('/auth/register') .set('Cookie', cookies) .send({ csrf: csrf, auth_method: 'magic_link', identifier: 'glimmer@example.org', }) .expect(302) .expect('Location', '/magic/lobby?redirect_uri=%2Fcsrf'); await followMagicLinkFromMail(agent, cookies); await testLogout(agent, cookies, csrf); // Verify saved user const email = await UserEmail.select() .with('user') .where('email', 'glimmer@example.org') .first(); const user = email?.user.getOrFail(); expect(user).toBeDefined(); expect(email).toBeDefined(); expect(email?.email).toStrictEqual('glimmer@example.org'); await expect(user?.as(UserPasswordComponent).verifyPassword('')).resolves.toStrictEqual(false); }); test('Cannot register taken email', async () => { const res = await agent.get('/csrf').expect(200); const cookies = res.get('Set-Cookie'); const csrf = res.text; await agent.post('/auth/register') .set('Cookie', cookies) .send({ csrf: csrf, auth_method: 'magic_link', identifier: 'bow@example.org', name: 'bow', }) .expect(302) .expect('Location', '/magic/lobby?redirect_uri=%2Fcsrf'); await followMagicLinkFromMail(agent, cookies); // Verify saved user const userEmail = await UserEmail.select() .with('user') .where('email', 'bow@example.org') .first(); const user = userEmail?.user.getOrFail(); expect(user).toBeDefined(); // Attempt register with another mail but same username const res2 = await agent.get('/csrf').expect(200); await agent.post('/auth/register') .set('Cookie', res2.get('Set-Cookie')) .send({ csrf: res2.text, auth_method: 'magic_link', identifier: 'bow@example.org', name: 'bow2', }) .expect(400); expect(await popEmail()).toBeNull(); }); });