const test = require('node:test'); const assert = require('node:assert/strict'); require('../src/common'); const registerAuthRoutes = require('../src/web/routes/auth'); const pages = require('../src/web/pages'); const renderLoginPage = require('../src/web/routes/auth/login'); const { createSessionService, normalizeReturnToPath } = require('../src/web/lib/auth/session'); test('two-factor login enables device trust, submits it, and resets it on back', async () => { const fs = require('node:fs'); const path = require('node:path'); const vm = require('node:vm'); const nodes = {}; const requests = []; let initialMessageRemoved = false; let redirectedTo; let submit; const form = { action: '/api/auth/sign-in/username', elements: { username: { value: 'demo' }, password: { value: 'password' }, remember_me: { checked: false }, trust_device: { disabled: true, checked: false }, two_factor_code: { disabled: true, value: '', focus() {} } }, querySelector(selector) { return nodes[selector] ||= { addEventListener(event, handler) { this[event] = handler; } }; }, addEventListener(event, handler) { submit = handler; } }; const scriptPath = path.join(__dirname, '../src/web/public/js/auth/login.js'); vm.runInNewContext(fs.readFileSync(scriptPath, 'utf8'), { document: { querySelector(selector) { if (selector === '[data-better-auth-login]') return form; if (selector === '[data-login-initial-message]' && !initialMessageRemoved) { return { remove() { initialMessageRemoved = true; } }; } return null; } }, window: { location: { search: '', assign(value) { redirectedTo = value; } } }, URLSearchParams, async fetch(endpoint, options) { assert.equal(initialMessageRemoved, true); requests.push({ endpoint, payload: JSON.parse(options.body) }); return { ok: true, async json() { return requests.length === 1 ? { twoFactorRedirect: true, twoFactorMethods: ['totp'] } : {}; } }; } }); await submit({ preventDefault() {} }); assert.equal(initialMessageRemoved, true); assert.equal(form.elements.trust_device.disabled, false); assert.equal(nodes['[data-login-feedback]'].hidden, true); assert.equal(redirectedTo, undefined); form.elements.trust_device.checked = true; form.elements.two_factor_code.value = '123456'; await submit({ preventDefault() {} }); assert.equal(requests[1].endpoint, '/api/auth/two-factor/verify-totp'); assert.equal(requests[1].payload.trustDevice, true); assert.equal(redirectedTo, '/'); nodes['[data-two-factor-back]'].click(); assert.equal(form.elements.trust_device.disabled, true); assert.equal(form.elements.trust_device.checked, false); }); test('login page preserves the return target in a hidden field', () => { const html = renderLoginPage('', '/slides/6/edit', 'demo'); assert.match(html, /name="returnTo"/); assert.match(html, /value="\/slides\/6\/edit"/); assert.match(html, /name="remember_me"/); assert.match(html, /action="\/api\/auth\/sign-in\/username"/); assert.match(html, /js\/auth\/login\.js/); assert.match(html, /name="username"[^>]*value="demo"/); assert.match(html, /data-login-two-factor/); assert.match(html, /name="two_factor_code"/); assert.match(html, /data-two-factor-toggle-method/); assert.doesNotMatch(html, /Sign in to start your session/); assert.match(html, /