import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import test from 'node:test'; import assert from 'node:assert/strict'; test('login persists authentication and skips the login page on later visits', async () => { const testDirectory = mkdtempSync(join(tmpdir(), 'local-kanban-auth-')); const token = 'test-only-auth-token'; process.env.KANBAN_CONFIG = join(testDirectory, 'config.json'); process.env.KANBAN_STATE = join(testDirectory, 'state.json'); process.env.KANBAN_AUTH_TOKEN = token; process.env.KANBAN_AUTH_SECURE_COOKIE = '1'; process.env.KANBAN_REQUIRE_HTTPS = '0'; const { createKanbanServer } = await import(`../src/server.js?auth-test=${Date.now()}`); const server = createKanbanServer(); try { await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)); const { port } = server.address(); const origin = `http://127.0.0.1:${port}`; const initialLoginPage = await fetch(`${origin}/login`, { redirect: 'manual' }); assert.equal(initialLoginPage.status, 200); const rejectedLogin = await fetch(`${origin}/api/auth/login`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ token: 'wrong-token' }) }); assert.equal(rejectedLogin.status, 401); assert.equal(rejectedLogin.headers.get('set-cookie'), null); const loginResponse = await fetch(`${origin}/api/auth/login`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ token }) }); assert.equal(loginResponse.status, 200); const setCookie = loginResponse.headers.get('set-cookie'); assert.match(setCookie, /^kanban_session=[^;]+;/); const cookie = setCookie.split(';', 1)[0]; const laterLoginPage = await fetch(`${origin}/login`, { headers: { cookie }, redirect: 'manual' }); assert.equal(laterLoginPage.status, 302); assert.equal(laterLoginPage.headers.get('location'), '/'); assert.match(setCookie, /Max-Age=31536000/); assert.match(setCookie, /HttpOnly/); assert.match(setCookie, /Secure/); const logoutResponse = await fetch(`${origin}/api/auth/logout`, { method: 'POST', headers: { cookie } }); assert.equal(logoutResponse.status, 200); assert.match(logoutResponse.headers.get('set-cookie'), /^kanban_session=;/); assert.match(logoutResponse.headers.get('set-cookie'), /Max-Age=0/); } finally { await new Promise((resolve) => server.close(resolve)); rmSync(testDirectory, { recursive: true, force: true }); } });