diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2487c00..933af0b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,4 +38,9 @@ jobs: # 3. Tests # Only runs if the code is clean and type-safe. - name: Test - run: bun test \ No newline at end of file + run: bun test + + # 4. Build (Final verification) + # This ensures your project can actually be deployed. + - name: Build + run: bun run build \ No newline at end of file diff --git a/nitro.config.ts b/nitro.config.ts new file mode 100644 index 0000000..7c45fc7 --- /dev/null +++ b/nitro.config.ts @@ -0,0 +1,51 @@ +import { defineNitroConfig } from "nitro/config"; + +export default defineNitroConfig({ + // Optimize for Bun since you are using it + preset: "bun", + + // Enable compression for static assets (gzip/brotli) + compressPublicAssets: true, + + routeRules: { + "/**": { + headers: { + // 1. Security: Block MIME type sniffing + "X-Content-Type-Options": "nosniff", + + // 2. Security: Prevent clickjacking (embedding in iframes) + "X-Frame-Options": "DENY", + + // 3. Privacy: Control how much referrer info is sent + "Referrer-Policy": "strict-origin-when-cross-origin", + + // 4. Security: Force HTTPS (HSTS) - Critical for production + // max-age=63072000 is 2 years. includeSubDomains covers subdomains. + "Strict-Transport-Security": + "max-age=63072000; includeSubDomains; preload", + + // 5. Hardware Access: Restrict access to sensitive device features + "Permissions-Policy": + "camera=(), microphone=(), geolocation=(), payment=(), usb=()", + + // 6. Content Security Policy (CSP) + // Allow scripts/images from 'self' and Cloudflare (for Turnstile). + // object-src 'none' prevents Flash/Java plugins (best practice). + // upgrade-insecure-requests forces HTTP links to load as HTTPS. + "Content-Security-Policy": [ + "default-src 'self'", + "script-src 'self' 'unsafe-inline' https://challenges.cloudflare.com", + "connect-src 'self' https://challenges.cloudflare.com", + "frame-src 'self' https://challenges.cloudflare.com", + "style-src 'self' 'unsafe-inline'", + "img-src 'self' data: https://challenges.cloudflare.com", + "font-src 'self' data:", + "object-src 'none'", + "base-uri 'self'", + "form-action 'self'", + "upgrade-insecure-requests", + ].join("; "), + }, + }, + }, +});