Files
refboard-ayon/tests/mock-exchange.js

55 lines
1.8 KiB
JavaScript

// Mock AYON addon exchange endpoint for E2E testing.
// POST /issue {ayon_user, display_name, project, task} -> {ticket}
// POST /exchange {ticket} -> identity payload (single-use, TTL 120s)
// NOT FOR PRODUCTION — test double only.
const http = require('http');
const crypto = require('crypto');
const tickets = new Map(); // ticket -> {payload, expires}
const TTL = 120000;
const json = (res, code, body) => {
const data = JSON.stringify(body);
res.writeHead(code, { 'Content-Type': 'application/json' });
res.end(data);
};
function readBody(req) {
return new Promise((resolve) => {
let raw = '';
req.on('data', (c) => (raw += c));
req.on('end', () => {
try { resolve(JSON.parse(raw || '{}')); } catch { resolve({}); }
});
});
}
const server = http.createServer(async (req, res) => {
const url = new URL(req.url, 'http://x');
// Simple API key check on /exchange (mirrors the real addon)
if (url.pathname === '/exchange') {
const key = process.env.REFBOARD_API_KEY || 'testkey';
if (req.headers['x-api-key'] !== key) {
return json(res, 401, { error: 'bad api key' });
}
const body = await readBody(req);
const t = tickets.get(body.ticket);
if (!t || t.expires < Date.now()) {
tickets.delete(body.ticket);
return json(res, 404, { error: 'unknown or expired ticket' });
}
tickets.delete(body.ticket); // single-use
return json(res, 200, t.payload);
}
if (url.pathname === '/issue') {
const body = await readBody(req);
const ticket = crypto.randomBytes(24).toString('hex');
tickets.set(ticket, { payload: body, expires: Date.now() + TTL });
return json(res, 200, { ticket });
}
if (url.pathname === '/health') return json(res, 200, { ok: true });
json(res, 404, { error: 'not found' });
});
server.listen(9000, () => console.log('mock exchange on 9000'));