Files
tools-legacy/tools/test/yrka-auth.test.js
T
adebisi-fa f03a75b9d2 feat: YOUreka Tools express app — landing page + fpagent enrollment wizard
- tools/: express host (hardcoded config, YOUreka Auth cookie session,
  OpenFGA domain filtering with 5-min cache, a2loft proxies)
- /fingerprint wizard: domain picker, two-finger capture via fpagent
  Socket.IO, OTP-validated lookup/save, domain refresh control
- node --test suite (27 tests, fake portal/PocketBase/a2loft upstreams)
- Dockerfile (node:22-alpine, non-root, healthcheck)
- README rewritten; node_modules gitignored

Field-verified end to end: portal login, permitted-domain filtering,
real U.are.U 4500 captures, cancel-preserves-capture, a2loft save.
2026-09-30 23:12:51 +01:00

93 lines
3.6 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import PocketBase from 'pocketbase';
import { loadYrkaSession, extractPbCookieValue, tokenExpiresAtMs } from '../yrka-auth.js';
import { makeJwt, makePbCookie, startServer, stopServer, urlOf, TEST_RECORD } from './helpers.js';
test('extractPbCookieValue handles prefixed and bare values', () => {
assert.equal(extractPbCookieValue('pb_auth=abc123; Path=/; HttpOnly'), 'abc123');
assert.equal(extractPbCookieValue('bare-value'), 'bare-value');
});
test('tokenExpiresAtMs reads exp from a JWT payload', () => {
const expSec = Math.floor(Date.now() / 1000) + 60;
const token = makeJwt({ expiresInSec: 60 });
assert.equal(tokenExpiresAtMs(token), expSec * 1000);
assert.equal(tokenExpiresAtMs('garbage'), 0);
assert.equal(tokenExpiresAtMs(''), 0);
});
test('loadYrkaSession returns null without a cookie', async () => {
assert.equal(await loadYrkaSession(''), null);
assert.equal(await loadYrkaSession(undefined), null);
});
test('loadYrkaSession returns null on malformed cookie values', async () => {
let constructed = false;
const pb = await loadYrkaSession('not-a-valid-envelope', {
pbUrl: 'http://127.0.0.1:9',
createPb: (url) => {
constructed = true;
return new PocketBase(url);
},
});
assert.equal(pb, null);
assert.equal(constructed, true, 'a PocketBase client was constructed before parsing failed');
});
// The remaining tests exercise the real SDK against a fake PocketBase server,
// so the cookie envelope and auth-refresh handling match production exactly.
async function withFakePb(refreshStatus, fn) {
const server = await startServer((req, res) => {
if (req.method === 'POST' && req.url.startsWith('/api/collections/users/auth-refresh')) {
res.writeHead(refreshStatus, { 'content-type': 'application/json' });
if (refreshStatus === 200) {
res.end(JSON.stringify({ token: makeJwt({ expiresInSec: 3600 }), record: TEST_RECORD }));
} else {
res.end(JSON.stringify({ code: 401, message: 'The request is not authenticated.' }));
}
return;
}
res.writeHead(404, { 'content-type': 'application/json' });
res.end('{}');
});
try {
await fn(urlOf(server));
} finally {
await stopServer(server);
}
}
test('loadYrkaSession accepts a valid, not-nearly-expired token without refreshing', async () => {
await withFakePb(200, async (pbUrl) => {
const cookie = makePbCookie(makeJwt({ expiresInSec: 3600 }));
const yrka = await loadYrkaSession(cookie, { pbUrl });
assert.ok(yrka);
assert.equal(yrka.refreshed, false);
assert.ok(yrka.pb.authStore.token);
assert.equal(yrka.pb.authStore.record.id, TEST_RECORD.id);
assert.equal(yrka.cookie, undefined);
});
});
test('loadYrkaSession refreshes proactively when expiry is within the buffer', async () => {
await withFakePb(200, async (pbUrl) => {
const oldToken = makeJwt({ expiresInSec: 60 }); // inside the 5-minute buffer
const cookie = makePbCookie(oldToken);
const yrka = await loadYrkaSession(cookie, { pbUrl });
assert.ok(yrka, 'session recovered');
assert.equal(yrka.refreshed, true);
assert.notEqual(yrka.pb.authStore.token, oldToken);
assert.ok(yrka.cookie, 'refreshed cookie value is returned for persistence');
});
});
test('loadYrkaSession returns null when the token is expired and refresh fails', async () => {
await withFakePb(401, async (pbUrl) => {
const cookie = makePbCookie(makeJwt({ expiresInSec: -3600 }));
const yrka = await loadYrkaSession(cookie, { pbUrl });
assert.equal(yrka, null);
});
});