Initial commit - Black Canyon Tickets whitelabel platform

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-08 12:31:31 -06:00
commit 997c129383
139 changed files with 60476 additions and 0 deletions

68
src/middleware.ts Normal file
View File

@@ -0,0 +1,68 @@
import { defineMiddleware } from 'astro/middleware';
export const onRequest = defineMiddleware((context, next) => {
// Security headers
const securityHeaders = {
// HTTPS enforcement
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload',
// XSS protection
'X-XSS-Protection': '1; mode=block',
// Content type sniffing protection
'X-Content-Type-Options': 'nosniff',
// Frame options (clickjacking protection)
'X-Frame-Options': 'DENY',
// Referrer policy
'Referrer-Policy': 'strict-origin-when-cross-origin',
// Content Security Policy
'Content-Security-Policy': [
"default-src 'self'",
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://m.stripe.network",
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
"font-src 'self' https://fonts.gstatic.com",
"img-src 'self' data: https: blob:",
"connect-src 'self' https://api.stripe.com https://*.supabase.co wss://*.supabase.co",
"frame-src 'self' https://js.stripe.com https://hooks.stripe.com",
"form-action 'self'",
"base-uri 'self'",
"object-src 'none'"
].join('; '),
// Permissions policy
'Permissions-Policy': [
'camera=(),',
'microphone=(),',
'geolocation=(),',
'payment=(self "https://js.stripe.com")',
'usb=(),',
'bluetooth=(),',
'magnetometer=(),',
'gyroscope=(),',
'accelerometer=()'
].join(' ')
};
// HTTPS redirect in production
if (process.env.NODE_ENV === 'production') {
const proto = context.request.headers.get('x-forwarded-proto');
const host = context.request.headers.get('host');
if (proto === 'http' && host) {
return Response.redirect(`https://${host}${context.url.pathname}${context.url.search}`, 301);
}
}
// Continue with the request
return next().then(response => {
// Add security headers to response
Object.entries(securityHeaders).forEach(([key, value]) => {
response.headers.set(key, value);
});
return response;
});
});