( req: Request, response: Response, allowedHosts: ReadonlySet<string>, )
| 285 | } as const; |
| 286 | |
| 287 | const withCorsHeaders = ( |
| 288 | req: Request, |
| 289 | response: Response, |
| 290 | allowedHosts: ReadonlySet<string>, |
| 291 | ): Response => { |
| 292 | const origin = req.headers.get("origin"); |
| 293 | // Same-origin requests carry no Origin header — nothing to do. Cross-origin |
| 294 | // requests only get credentialed CORS if their Origin is an allowed loopback |
| 295 | // host; an arbitrary web page (e.g. https://evil.example) gets no ACAO, so |
| 296 | // the browser blocks it reading the response even if it knew the token. |
| 297 | if (!origin || !isAllowedOrigin(origin, allowedHosts)) return response; |
| 298 | const headers = new Headers(response.headers); |
| 299 | headers.set("access-control-allow-origin", origin); |
| 300 | for (const [key, value] of Object.entries(corsHeaders)) headers.set(key, value); |
| 301 | headers.set( |
| 302 | "access-control-allow-headers", |
| 303 | req.headers.get("access-control-request-headers") ?? |
| 304 | corsHeaders["access-control-allow-headers"], |
| 305 | ); |
| 306 | headers.append("vary", "Origin"); |
| 307 | return new Response(response.body, { |
| 308 | status: response.status, |
| 309 | statusText: response.statusText, |
| 310 | headers, |
| 311 | }); |
| 312 | }; |
| 313 | |
| 314 | const corsPreflightResponse = (req: Request, allowedHosts: ReadonlySet<string>): Response => |
| 315 | withCorsHeaders(req, new Response(null, { status: 204 }), allowedHosts); |
no test coverage detected