// Checks for the extension's Vest relay: the hook in the Vest tab // (extension/vest-relay.js) and the choice of which tab's token the background // relays (extension/background.js pageVestSession / pickVestSession). // // npm run check // // The hook runs in a sandbox standing in for the Vest page — its own XHR and // fetch, answered here; the background's functions are lifted out of its // source, since it is a service worker and not a module. Nothing reaches Vest // or Chrome. The answers are shaped like the Vest app's own (index bundle, // 2026-10-29): a renewal's carries refreshTokenId, a sign-in's the login's // refreshToken too, an account's renewal a refreshToken in its request. import { test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import vm from 'node:vm'; const read = (path) => readFileSync(new URL(`../${path}`, import.meta.url), 'utf8'); const HOOK = read('extension/vest-relay.js'); const BACKGROUND = read('extension/background.js'); const GATEWAY = 'https://api-gateway.hz.vestmarkets.com'; const WALLET = '0x7ce10771819f80130e204ddb5ca1522e48a9b451'; const answer = (extra) => JSON.stringify({ accessToken: 'eyJ.login.sig', accessExpiresAtMs: 1_800_000_000_000, primaryAddr: WALLET, userId: 'u', ...extra }); /** A Vest page with the hook run in it (after `before`, a hook already * there): `xhr(url, body, status, text)` and `fetch(...)` play one of the * app's requests through it. */ function page(before = {}) { class FakeXHR { constructor() { this.listeners = []; this.responseType = ''; } open(method, url) { this.url = url; } send() {} addEventListener(type, fn) { if (type === 'loadend') this.listeners.push(fn); } } const answers = []; const sandbox = { XMLHttpRequest: FakeXHR, URL, fetch: async () => answers.shift(), ...before, }; sandbox.window = sandbox; vm.createContext(sandbox); vm.runInContext(HOOK, sandbox); return { sandbox, run: () => vm.runInContext(HOOK, sandbox), xhr(url, body, status, text) { const x = new sandbox.XMLHttpRequest(); x.open('POST', url); x.send(body); x.status = status; x.responseText = text; for (const fn of x.listeners) fn(); }, async fetch(url, body, status, text) { answers.push({ status, clone: () => ({ text: async () => text }) }); await sandbox.window.fetch(url, { method: 'POST', body }); await new Promise((resolve) => setImmediate(resolve)); }, }; } test("the hook keeps the login's renewed token with its session id, and an account's never", async () => { const p = page(); assert.equal(p.sandbox.__afVestHook, 2); p.xhr(`${GATEWAY}/v3/auth/refresh`, JSON.stringify({ requestId: 'r1', rememberMe: true }), 200, answer({ refreshTokenId: 'rt-1' })); assert.equal(p.sandbox.__afVestLogin.accessToken, 'eyJ.login.sig'); assert.equal(p.sandbox.__afVestLogin.refreshTokenId, 'rt-1'); assert.equal(p.sandbox.__afVestLogin.primaryAddr, WALLET); // An account's renewal, by its request, then by its answer alone. p.xhr(`${GATEWAY}/v3/auth/refresh`, JSON.stringify({ refreshToken: 'acct-rt', requestId: 'r2' }), 200, answer({ accessToken: 'eyJ.acct.sig', refreshTokenId: 'rt-a' })); await p.fetch(`${GATEWAY}/v3/auth/refresh`, undefined, 200, answer({ accessToken: 'eyJ.acct2.sig', refreshToken: 'acct-rt', refreshTokenId: 'rt-b' })); assert.equal(p.sandbox.__afVestLogin.accessToken, 'eyJ.login.sig'); // The login's next renewal, through fetch; a refused one leaves it be. await p.fetch(`${GATEWAY}/v3/auth/refresh`, JSON.stringify({ requestId: 'r3' }), 200, answer({ accessToken: 'eyJ.login2.sig', refreshTokenId: 'rt-2' })); p.xhr(`${GATEWAY}/v3/auth/refresh`, JSON.stringify({ requestId: 'r4' }), 401, answer({ accessToken: 'eyJ.no.sig', refreshTokenId: 'rt-x' })); assert.equal(p.sandbox.__afVestLogin.accessToken, 'eyJ.login2.sig'); assert.equal(p.sandbox.__afVestLogin.refreshTokenId, 'rt-2'); }); test("a sign-in's token is taken, though its answer carries the login's refresh token", () => { const p = page(); p.xhr(`${GATEWAY}/v3/auth/register`, JSON.stringify({ primaryAddr: WALLET }), 200, answer({ accessToken: 'eyJ.signin.sig', refreshToken: 'login-rt', refreshTokenId: 'rt-s' })); assert.equal(p.sandbox.__afVestLogin.accessToken, 'eyJ.signin.sig'); assert.equal(p.sandbox.__afVestLogin.refreshTokenId, 'rt-s'); }); test('the hook installs once, and beside a version-1 hook', () => { const p = page({ __afVestHook: true, __afVestSession: { accessToken: 'eyJ.old.sig', expiresAt: 1 } }); assert.equal(p.sandbox.__afVestHook, 2); const send = p.sandbox.XMLHttpRequest.prototype.send; p.run(); assert.equal(p.sandbox.XMLHttpRequest.prototype.send, send); }); // The background's own functions, out of its source. function lift(name) { const m = BACKGROUND.match(new RegExp(`^function ${name}\\([\\s\\S]*?^}`, 'm')); assert.ok(m, `${name} not found in background.js`); return m[0]; } const { isCurrentVestSession, pickVestSession } = new Function(`${lift('isCurrentVestSession')}\n${lift('pickVestSession')}\nreturn { isCurrentVestSession, pickVestSession };`)(); const pageVestSession = (window, stored) => new Function('window', 'localStorage', `${lift('pageVestSession')}\nreturn pageVestSession();`)( window, { getItem: (key) => (key === 'vest-auth-session' ? stored : null) }, ); const later = (min) => Date.now() + min * 60_000; const session = (token, expiresAt, refreshTokenId) => ({ accessToken: token, expiresAt, primaryAddr: WALLET, userId: 'u', ...(refreshTokenId !== undefined ? { refreshTokenId } : {}) }); const record = (refreshTokenId, accessTokenExpiresAt) => JSON.stringify({ refreshTokenId, accessTokenExpiresAt, refreshTokenExpiresAt: later(43200), rememberMe: true }); test("a tab reports its live token (version 2's, else version 1's) and the app's current session", () => { const expiresAt = later(12); let out = pageVestSession({ __afVestHook: 2, __afVestLogin: session('eyJ.v2.sig', expiresAt, 'rt-2'), __afVestSession: session('eyJ.v1.sig', expiresAt) }, record('rt-2', expiresAt)); assert.equal(out.hooked, true); assert.equal(out.session.accessToken, 'eyJ.v2.sig'); assert.deepEqual(out.current, { refreshTokenId: 'rt-2', accessTokenExpiresAt: expiresAt }); // Hooked by version 1 only: its token, and the tab asks for version 2. out = pageVestSession({ __afVestHook: true, __afVestSession: session('eyJ.v1.sig', later(9)) }, record('rt-3', later(14))); assert.equal(out.hooked, false); assert.equal(out.session.accessToken, 'eyJ.v1.sig'); // A 0.17.0 hook kept an account's renewal too: version 2's login token // wins over it, though it expires sooner. out = pageVestSession({ __afVestHook: 2, __afVestLogin: session('eyJ.v2.sig', later(5), 'rt-1'), __afVestSession: session('eyJ.acct.sig', later(13)) }, null); assert.equal(out.session.accessToken, 'eyJ.v2.sig'); assert.equal(out.current, null); // Nearly expired, or a record that doesn't read. out = pageVestSession({ __afVestHook: 2, __afVestLogin: session('eyJ.v2.sig', Date.now() + 20_000, 'rt-1') }, '{nope'); assert.equal(out.session, null); assert.equal(out.current, null); }); test("the token relayed is the one the current session holds, whichever tab has it — not the first tab's", () => { // Tab 1 renewed first; tab 2 renewed after it, so the session is tab 2's. const tab1 = { hooked: true, session: session('eyJ.tab1.sig', later(6), 'rt-1'), current: { refreshTokenId: 'rt-2', accessTokenExpiresAt: later(13) } }; const tab2 = { hooked: true, session: session('eyJ.tab2.sig', later(13), 'rt-2'), current: { refreshTokenId: 'rt-2', accessTokenExpiresAt: later(13) } }; assert.deepEqual(pickVestSession([tab1, tab2]), { session: tab2.session, current: true }); assert.equal(isCurrentVestSession(tab1.session, tab1.current), false); // Tab 1 renews again: now its token is the current one. const rt3 = { refreshTokenId: 'rt-3', accessTokenExpiresAt: later(15) }; const tab1b = { ...tab1, session: session('eyJ.tab1b.sig', later(15), 'rt-3'), current: rt3 }; assert.equal(pickVestSession([{ ...tab2, current: rt3 }, tab1b]).session.accessToken, 'eyJ.tab1b.sig'); // Version-1 hooks keep no id: matched by the expiry the app keeps with it. const v1a = { hooked: false, session: session('eyJ.v1a.sig', later(4)), current: { refreshTokenId: 'rt-9', accessTokenExpiresAt: later(11) } }; const v1b = { hooked: false, session: session('eyJ.v1b.sig', v1a.current.accessTokenExpiresAt), current: v1a.current }; assert.deepEqual(pickVestSession([v1a, v1b]), { session: v1b.session, current: true }); }); test('with no tab holding the current session the newest is relayed, and said; with no record, unjudged', () => { const current = { refreshTokenId: 'rt-5', accessTokenExpiresAt: later(14) }; const a = { hooked: true, session: session('eyJ.a.sig', later(3), 'rt-3'), current }; const b = { hooked: true, session: session('eyJ.b.sig', later(8), 'rt-4'), current }; assert.deepEqual(pickVestSession([a, b]), { session: b.session, current: false }); assert.deepEqual(pickVestSession([{ ...a, current: null }, { ...b, current: null }]), { session: b.session, current: null }); // A tab with no token yet still shows the record. assert.equal(pickVestSession([{ hooked: true, session: null, current }, { ...b, current: null }]).current, false); assert.equal(pickVestSession([{ hooked: true, session: null, current }]), null); assert.equal(pickVestSession([]), null); });