#!/usr/bin/env node // Test helper: an Authentik-like auth proxy in front of a DSH master. // node deploy/fake-edge.mjs // Unauthenticated → 302 to a fake login page; Basic user:password → session cookie + // pass-through (HTTP and WebSocket upgrades); session cookie → pass-through. import crypto from 'node:crypto' import http from 'node:http' import net from 'node:net' const [port, upstream, user, pass] = process.argv.slice(2) const up = new URL(upstream) const sessions = new Set() const want = `Basic ${Buffer.from(`${user}:${pass}`).toString('base64')}` const stats = { redirects: 0, credentialLogins: 0, cookieHits: 0, upgrades: 0 } function auth(req) { const sid = /edge_session=([a-f0-9]+)/.exec(req.headers.cookie || '')?.[1] if (sid && sessions.has(sid)) { stats.cookieHits++; return { ok: true } } if (req.headers.authorization === want) { stats.credentialLogins++ const id = crypto.randomBytes(12).toString('hex') sessions.add(id) return { ok: true, setCookie: `edge_session=${id}; Path=/; HttpOnly; Max-Age=86400` } } if (req.headers.authorization) return { ok: false, status: 401 } return { ok: false, status: 302 } } const strip = (h) => { const o = { ...h }; delete o.authorization; return o } const srv = http.createServer((req, res) => { if (req.url === '/__stats') { res.end(JSON.stringify(stats)); return } const a = auth(req) if (!a.ok) { if (a.status === 302) stats.redirects++ res.writeHead(a.status, a.status === 302 ? { location: 'https://auth.example/application/o/authorize/?client_id=x' } : {}) return res.end() } const p = http.request({ host: up.hostname, port: up.port, method: req.method, path: req.url, headers: { ...strip(req.headers), host: up.host } }, (r) => { const h = { ...r.headers } if (a.setCookie) h['set-cookie'] = [a.setCookie, ...(h['set-cookie'] || [])] res.writeHead(r.statusCode, h) r.pipe(res) }) p.on('error', () => { res.writeHead(502); res.end() }) req.pipe(p) }) srv.on('upgrade', (req, socket, head) => { const a = auth(req) if (!a.ok) { if (a.status === 302) stats.redirects++ socket.end(a.status === 302 ? 'HTTP/1.1 302 Found\r\nLocation: https://auth.example/login\r\nContent-Length: 0\r\n\r\n' : 'HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\n\r\n') return } stats.upgrades++ const s = net.connect(Number(up.port), up.hostname, () => { const lines = [`${req.method} ${req.url} HTTP/1.1`] for (const [k, v] of Object.entries({ ...strip(req.headers), host: up.host })) for (const one of [].concat(v)) lines.push(`${k}: ${one}`) s.write(lines.join('\r\n') + '\r\n\r\n') if (head?.length) s.write(head) s.pipe(socket); socket.pipe(s) }) s.on('error', () => socket.destroy()) socket.on('error', () => s.destroy()) }) srv.listen(Number(port), '127.0.0.1', () => console.log(`fake edge on 127.0.0.1:${port} → ${upstream}`))