import assert from 'node:assert/strict'; import test from 'node:test'; import { createPortalAuthSessionHelpers } from './portal-auth-session-helpers.mjs'; function createRequest(cookie = '', overrides = {}) { return { headers: {}, hostname: 'm.example.com', protocol: 'https', get(name) { if (String(name).toLowerCase() === 'cookie') return cookie; if (String(name).toLowerCase() === 'host') { return this.headers.host ?? this.hostname; } return this.headers[String(name).toLowerCase()]; }, ...overrides, }; } function createResponse() { return { headers: {}, set(name, value) { this.headers[name] = value; return this; }, }; } test('auth session helpers parse legacy and user cookies', () => { const helpers = createPortalAuthSessionHelpers({ isSecureRequest: () => false, }); const req = createRequest( 'tkmind_h5_session=legacy-token; tkmind_user_session=user-token', ); assert.equal(helpers.legacySessionToken(req), 'legacy-token'); assert.equal(helpers.userToken(req), 'user-token'); }); test('auth session helpers set and clear user login cookies', () => { const helpers = createPortalAuthSessionHelpers({ isSecureRequest: () => true, getLegacyAuth: () => ({}), }); const req = createRequest('', { headers: { host: 'm.tkmind.cn' }, }); const loginRes = createResponse(); helpers.setUserLoginCookies(loginRes, req, 'user-token'); const loginCookies = loginRes.headers['Set-Cookie']; assert.ok(Array.isArray(loginCookies)); assert.ok( loginCookies.some((cookie) => cookie.includes('tkmind_user_session=user-token'), ), ); assert.ok( loginCookies.every((cookie) => cookie.includes('Secure')), ); const logoutRes = createResponse(); helpers.clearUserLoginCookies(logoutRes, req); const logoutCookies = logoutRes.headers['Set-Cookie']; assert.ok( logoutCookies.some((cookie) => cookie.includes('tkmind_user_session='), ), ); assert.ok( logoutCookies.some((cookie) => cookie.includes('tkmind_h5_session='), ), ); }); test('attachUserSession verifies the user token and populates request state', async () => { const calls = []; const helpers = createPortalAuthSessionHelpers({ isSecureRequest: () => false, getUserAuth: () => ({ async verify(token) { calls.push(token); return { userId: 'user-1' }; }, }), }); const req = createRequest( 'tkmind_user_session=user-token', ); let nextCalls = 0; await helpers.attachUserSession(req, {}, () => { nextCalls += 1; }); assert.deepEqual(calls, ['user-token']); assert.deepEqual(req.userSession, { userId: 'user-1' }); assert.equal(req.userSessionError, null); assert.equal(nextCalls, 1); }); test('attachUserSession records verification failure and always continues', async () => { const logs = []; const failure = new Error('database unavailable'); const helpers = createPortalAuthSessionHelpers({ isSecureRequest: () => false, getUserAuth: () => ({ async verify() { throw failure; }, }), logger: { error(...args) { logs.push(args); }, }, }); const req = createRequest( 'tkmind_user_session=user-token', ); let nextCalls = 0; await helpers.attachUserSession(req, {}, () => { nextCalls += 1; }); assert.equal(req.userSession, null); assert.equal(req.userSessionError, failure); assert.equal(nextCalls, 1); assert.deepEqual(logs[0], [ '[Auth] session verify failed:', 'database unavailable', ]); const noAuthHelpers = createPortalAuthSessionHelpers({ isSecureRequest: () => false, }); const noAuthReq = createRequest(); await noAuthHelpers.attachUserSession(noAuthReq, {}, () => { nextCalls += 1; }); assert.equal(nextCalls, 2); assert.equal(noAuthReq.userToken, undefined); });