| ... | @@ -43,6 +43,18 @@ import { browserApiCorsAllowedHeaders, browserApiCorsAllowedMethods } from "./ht | ... | @@ -43,6 +43,18 @@ import { browserApiCorsAllowedHeaders, browserApiCorsAllowedMethods } from "./ht |
| 43 | const OTLP_TRACES_PROXY_PATH = "/api/observability/v1/traces"; | 43 | const OTLP_TRACES_PROXY_PATH = "/api/observability/v1/traces"; |
| 44 | const LOOPBACK_HOSTNAMES = new Set(["127.0.0.1", "::1", "localhost"]); | 44 | const LOOPBACK_HOSTNAMES = new Set(["127.0.0.1", "::1", "localhost"]); |
| 45 | const DESKTOP_RENDERER_ORIGINS = ["t3code://app", "t3code-dev://app"]; | 45 | const DESKTOP_RENDERER_ORIGINS = ["t3code://app", "t3code-dev://app"]; |
| | 46 | const SVG_CONTENT_SECURITY_POLICY = "default-src 'none'; style-src 'unsafe-inline'; sandbox"; |
| | 47 | |
| | 48 | export function assetResponseHeaders(filePath: string): Record<string, string> { |
| | 49 | return { |
| | 50 | "Cache-Control": "private, max-age=3600", |
| | 51 | "X-Content-Type-Options": "nosniff", |
| | 52 | ...(filePath.toLowerCase().endsWith(".svg") |
| | 53 | ? { "Content-Security-Policy": SVG_CONTENT_SECURITY_POLICY } |
| | 54 | : {}), |
| | 55 | }; |
| | 56 | } |
| | 57 | |
| 46 | export const httpCompressionLayer = HttpRouter.middleware(HttpMiddleware.compression(), { | 58 | export const httpCompressionLayer = HttpRouter.middleware(HttpMiddleware.compression(), { |
| 47 | global: true, | 59 | global: true, |
| 48 | }); | 60 | }); |
| ... | @@ -207,10 +219,7 @@ export const assetRouteLayer = HttpRouter.add( | ... | @@ -207,10 +219,7 @@ export const assetRouteLayer = HttpRouter.add( |
| 207 | } | 219 | } |
| 208 | return yield* HttpServerResponse.file(asset.path, { | 220 | return yield* HttpServerResponse.file(asset.path, { |
| 209 | status: 200, | 221 | status: 200, |
| 210 | headers: { | 222 | headers: assetResponseHeaders(asset.path), |
| 211 | "Cache-Control": "private, max-age=3600", | | |
| 212 | "X-Content-Type-Options": "nosniff", | | |
| 213 | }, | | |
| 214 | }).pipe( | 223 | }).pipe( |
| 215 | Effect.orElseSucceed(() => HttpServerResponse.text("Internal Server Error", { status: 500 })), | 224 | Effect.orElseSucceed(() => HttpServerResponse.text("Internal Server Error", { status: 500 })), |
| 216 | ); | 225 | ); |