All files / server/proxy content-security-policy.ts

100% Statements 9/9
50% Branches 7/14
100% Functions 1/1
100% Lines 8/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45          1x         53x 53x 53x   53x                                               53x   53x   53x    
import type { NextRequest, NextResponse } from 'next/server';
 
/**
 * @see https://vercel.com/docs/vercel-toolbar/managing-toolbar#using-a-content-security-policy
 */
export const contentSecurityPolicy = (
  request: NextRequest,
  response: NextResponse,
): NextResponse => {
  // stele:landmark csp-dynamic
  const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
  const preview = process.env['VERCEL_ENV'] === 'preview';
  const production = process.env.NODE_ENV !== 'development';
 
  const policy = [
    "default-src 'none';",
    "base-uri 'self';",
    `connect-src ${preview ? "'self' https://vercel.live wss://ws-us3.pusher.com" : "'self'"};`,
 
    `font-src ${preview ? "'self' https://assets.vercel.com https://vercel.live" : "'self'"};`,
    "form-action 'self';",
    `frame-src ${preview ? 'https://vercel.live' : "'none'"};`,
    `img-src ${
      preview ? "'self' https://vercel.com https://vercel.live blob: data:" : "'self' blob: data:"
    };`,
    // wasm-unsafe-eval: WebAssembly.instantiate() for the Bevy background wasm module.
    `script-src 'wasm-unsafe-eval' ${
      production
        ? `'self' 'nonce-${nonce}' ${preview ? 'https://vercel.live' : "'strict-dynamic'"}`
        : `'self' 'nonce-${nonce}' 'strict-dynamic' 'unsafe-eval'`
    };`,
    `style-src ${
      preview ? "'self' https://vercel.live 'unsafe-inline'" : "'self' 'unsafe-inline'"
    };`,
 
    'upgrade-insecure-requests;',
  ].join(' ');
 
  request.headers.set('x-nonce', nonce);
 
  response.headers.set('content-security-policy', policy);
 
  return response;
};