Something went wrong. Try again.
small gleam coding and (not yet) persistent agent daemon with a detachable cli forked from okami.mom/albedo
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121// The daemon E2E suite does not exercise Vite's WebSocket upgrade hooks.import assert from 'node:assert/strict';import { createHash } from 'node:crypto';import { once } from 'node:events';import { mkdtemp, rm, writeFile } from 'node:fs/promises';import { createServer as createHTTPServer } from 'node:http';import { connect } from 'node:net';import { tmpdir } from 'node:os';import { join } from 'node:path';import test from 'node:test';import { fileURLToPath } from 'node:url';import { createServer } from 'vite';
function readUntil(socket, complete) { return new Promise((resolve, reject) => { let received = Buffer.alloc(0); const cleanup = () => { socket.off('data', data); socket.off('error', error); socket.off('close', closed); }; const error = (reason) => { cleanup(); reject(reason); }; const closed = () => error(new Error('socket closed before its reply')); const data = (chunk) => { received = Buffer.concat([received, chunk]); if (complete(received)) { cleanup(); resolve(received); } }; socket.on('data', data); socket.once('error', error); socket.once('close', closed); });}
test('Vite upgrades /api/events with the daemon token and without browser headers', { timeout: 10000 }, async () => { const home = await mkdtemp(join(tmpdir(), 'albedo-vite-proxy-')); const previousHome = process.env.ALBEDO_HOME; const backend = createHTTPServer(); const upstreamSockets = new Set(); let upgrades = 0; backend.on('connection', (socket) => { upstreamSockets.add(socket); socket.on('close', () => upstreamSockets.delete(socket)); }); const upgraded = new Promise((resolve) => { backend.on('upgrade', (request, socket) => { upgrades++; resolve(request); const accept = createHash('sha1') .update(request.headers['sec-websocket-key'] + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11') .digest('base64'); socket.write('HTTP/1.1 101 Switching Protocols\r\n' + 'Connection: Upgrade\r\nUpgrade: websocket\r\n' + `Sec-WebSocket-Accept: ${accept}\r\n\r\n`); socket.on('data', (chunk) => socket.write(chunk)); }); }); let vite; let client; let forbidden; try { await new Promise((resolve) => backend.listen(0, '127.0.0.1', resolve)); await writeFile(join(home, 'daemon.json'), JSON.stringify({ port: backend.address().port, token: 'daemon-secret', })); process.env.ALBEDO_HOME = home; const root = fileURLToPath(new URL('..', import.meta.url)); vite = await createServer({ root, configFile: join(root, 'vite.config.ts'), logLevel: 'silent', server: { host: '127.0.0.1', port: 0, open: false, hmr: false, watch: null }, optimizeDeps: { noDiscovery: true, include: [] }, }); await vite.listen(); const port = vite.httpServer.address().port; client = connect({ host: '127.0.0.1', port }); client.setTimeout(5000, () => client.destroy(new Error('proxy handshake timed out'))); await once(client, 'connect'); const reply = readUntil(client, (data) => data.includes('\r\n\r\n')); const handshake = `GET /api/events HTTP/1.1\r\nHost: 127.0.0.1:${port}\r\n` + 'Connection: Upgrade\r\nUpgrade: websocket\r\n' + 'Sec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n' + `Origin: http://127.0.0.1:${port}\r\n` + `Referer: http://127.0.0.1:${port}/\r\n` + 'Cookie: albedo_web=browser-cookie\r\nAuthorization: Bearer browser-supplied\r\n\r\n'; client.write(handshake); const headers = (await reply).toString(); assert.match(headers, /^HTTP\/1\.1 101 /); assert.match(headers, /sec-websocket-accept: s3pPLMBiTxaQ9kYGzzhZRbK\+xOo=/i); assert.ok(!headers.includes('daemon-secret')); const forwarded = await upgraded; assert.equal(forwarded.url, '/events'); assert.equal(forwarded.headers.authorization, 'Bearer daemon-secret'); for (const header of ['origin', 'cookie', 'referer']) { assert.equal(forwarded.headers[header], undefined, `forwarded browser ${header}`); } const frame = Buffer.from([0x81, 0x82, 1, 2, 3, 4, 'o'.charCodeAt(0) ^ 1, 'k'.charCodeAt(0) ^ 2]); const echo = readUntil(client, (data) => data.length >= frame.length); client.write(frame); assert.deepEqual(await echo, frame); assert.equal(upgrades, 1);
forbidden = connect({ host: '127.0.0.1', port }); forbidden.setTimeout(5000, () => forbidden.destroy(new Error('origin rejection timed out'))); await once(forbidden, 'connect'); const rejection = readUntil(forbidden, (data) => data.includes('\r\n\r\n')); forbidden.write(handshake.replace(`Origin: http://127.0.0.1:${port}`, 'Origin: https://evil.example')); assert.match((await rejection).toString(), /^HTTP\/1\.1 403 /); assert.equal(upgrades, 1, 'foreign origin reached the daemon'); } finally { client?.destroy(); forbidden?.destroy(); for (const socket of upstreamSockets) socket.destroy(); await vite?.close(); await new Promise((resolve) => backend.close(resolve)); if (previousHome === undefined) delete process.env.ALBEDO_HOME; else process.env.ALBEDO_HOME = previousHome; await rm(home, { recursive: true, force: true }); }});