| 73 | /** Upstream on 127.0.0.1 that authenticates for real: `GET /issues` is 200 for |
| 74 | * any bearer it has not been told to reject, and 401 for one it has. */ |
| 75 | const serveUpstream = () => |
| 76 | Effect.acquireRelease( |
| 77 | Effect.callback<UpstreamHandle>((resume) => { |
| 78 | const seen: string[] = []; |
| 79 | const revoked = new Set<string>(); |
| 80 | const server = createServer((request, response) => { |
| 81 | const bearer = (request.headers.authorization ?? "").replace(/^Bearer\s+/i, ""); |
| 82 | if (request.method === "GET" && (request.url ?? "").startsWith("/issues")) { |
| 83 | seen.push(bearer); |
| 84 | if (revoked.has(bearer)) { |
| 85 | response.writeHead(401, { "content-type": "application/json" }); |
| 86 | response.end(JSON.stringify({ error: "invalid_token" })); |
| 87 | return; |
| 88 | } |
| 89 | response.writeHead(200, { "content-type": "application/json" }); |
| 90 | response.end(JSON.stringify({ issues: [{ id: 1, title: "first" }] })); |
| 91 | return; |
| 92 | } |
| 93 | response.writeHead(404, { "content-type": "application/json" }); |
| 94 | response.end(JSON.stringify({ error: "not_found" })); |
| 95 | }); |
| 96 | server.listen(0, "127.0.0.1", () => { |
| 97 | const address = server.address(); |
| 98 | const port = typeof address === "object" && address ? address.port : 0; |
| 99 | resume( |
| 100 | Effect.succeed({ |
| 101 | url: `http://127.0.0.1:${port}`, |
| 102 | revokeSeenBearers: () => { |
| 103 | for (const bearer of seen) revoked.add(bearer); |
| 104 | }, |
| 105 | close: () => { |
| 106 | server.close(); |
| 107 | server.closeAllConnections(); |
| 108 | }, |
| 109 | }), |
| 110 | ); |
| 111 | }); |
| 112 | }), |
| 113 | (server) => Effect.sync(server.close), |
| 114 | ); |
| 115 | |
| 116 | const spec = ( |
| 117 | baseUrl: string, |