( req: Request, nonce: string | null, )
| 37 | } |
| 38 | |
| 39 | async function proxyFetch( |
| 40 | req: Request, |
| 41 | nonce: string | null, |
| 42 | ): Promise<Response> { |
| 43 | if (nonce && req.headers.get('x-auth-nonce') !== nonce) { |
| 44 | return new Response('Forbidden', { status: 403 }) |
| 45 | } |
| 46 | |
| 47 | const upstreamBase = resolveUpstreamBaseUrl() |
| 48 | const url = new URL(req.url) |
| 49 | const upstreamUrl = `${upstreamBase}${url.pathname}${url.search}` |
| 50 | |
| 51 | const authHeaders = resolveAuthHeaders() |
| 52 | if (Object.keys(authHeaders).length === 0) { |
| 53 | return new Response( |
| 54 | JSON.stringify({ |
| 55 | error: 'No API credentials available on local machine', |
| 56 | }), |
| 57 | { status: 401, headers: { 'content-type': 'application/json' } }, |
| 58 | ) |
| 59 | } |
| 60 | |
| 61 | const forwardHeaders = new Headers(req.headers) |
| 62 | for (const [k, v] of Object.entries(authHeaders)) { |
| 63 | forwardHeaders.set(k, v) |
| 64 | } |
| 65 | forwardHeaders.delete('host') |
| 66 | forwardHeaders.delete('x-auth-nonce') |
| 67 | |
| 68 | logForDebugging( |
| 69 | `[SSHAuthProxy] ${req.method} ${url.pathname} -> ${upstreamUrl}`, |
| 70 | ) |
| 71 | |
| 72 | try { |
| 73 | const upstreamRes = await fetch(upstreamUrl, { |
| 74 | method: req.method, |
| 75 | headers: forwardHeaders, |
| 76 | body: req.body, |
| 77 | // @ts-expect-error Bun supports duplex for streaming request bodies |
| 78 | duplex: 'half', |
| 79 | }) |
| 80 | |
| 81 | const responseHeaders = new Headers(upstreamRes.headers) |
| 82 | responseHeaders.delete('content-encoding') |
| 83 | responseHeaders.delete('content-length') |
| 84 | |
| 85 | return new Response(upstreamRes.body, { |
| 86 | status: upstreamRes.status, |
| 87 | statusText: upstreamRes.statusText, |
| 88 | headers: responseHeaders, |
| 89 | }) |
| 90 | } catch (err) { |
| 91 | const message = err instanceof Error ? err.message : String(err) |
| 92 | logForDebugging(`[SSHAuthProxy] upstream error: ${message}`) |
| 93 | return new Response( |
| 94 | JSON.stringify({ error: `Proxy upstream error: ${message}` }), |
| 95 | { status: 502, headers: { 'content-type': 'application/json' } }, |
| 96 | ) |
no test coverage detected