mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
DNS (Cloudflare) and the Vercel domain are already provisioned by the operator; this lands the matching code-side wiring so the variant actually resolves and renders correctly. Changes: middleware.ts - Add `'energy.worldmonitor.app': 'energy'` to VARIANT_HOST_MAP. This also auto-includes the host in ALLOWED_HOSTS via the spread on line 87. - Add `energy` entry to VARIANT_OG with the Energy-Atlas-specific title + description from `src/config/variant-meta.ts:130-152`. OG image points at `https://energy.worldmonitor.app/favico/energy/og-image.png`, matching the per-variant convention used by tech / finance / commodity / happy. vercel.json - Add `https://energy.worldmonitor.app` to BOTH `frame-src` and `frame-ancestors` in the global Content-Security-Policy header. Without this, the variant subdomain would render but be blocked from being framed back into worldmonitor.app for any embedded flow (Slack/LinkedIn previews, future iframe widgets, etc.). This supersedes the CSP-only portion of PR #3359 (which mixed CSP with unrelated relay/military changes). convex/payments/checkout.ts:108-117 - Add `https://energy.worldmonitor.app` to the checkout returnUrl allowlist. Without this, a PRO upgrade flow initiated from the energy subdomain would fail with "Invalid returnUrl" on Convex. src-tauri/tauri.conf.json:32 - Add `https://energy.worldmonitor.app` to the Tauri desktop CSP frame-src so the desktop app can embed the variant the same way it embeds the other 4. public/favico/energy/* (NEW, 7 files) - Stub the per-variant favicon directory by copying the root-level WorldMonitor brand assets (android-chrome 192/512, apple-touch, favicon 16/32/ico, og-image). This keeps the launch unblocked on design assets — every referenced URL resolves with valid bytes from day one. Replace with energy-themed designs in a follow-up PR; the file paths are stable. Other variant subdomains already on main (tech / finance / commodity / happy) are unchanged. APP_HOSTS in src/services/runtime.ts already admits any `*.worldmonitor.app` via `host.endsWith('.worldmonitor.app')` on line 226, so no edit needed there. Closes gaps §L #9, #10, #11 in docs/internal/energy-atlas-registry-expansion.md.
218 lines
12 KiB
JSON
218 lines
12 KiB
JSON
{
|
|
"ignoreCommand": "bash scripts/vercel-ignore.sh",
|
|
"crons": [],
|
|
"redirects": [
|
|
{ "source": "/docs", "destination": "/docs/documentation", "permanent": false },
|
|
{ "source": "/security.txt", "destination": "/.well-known/security.txt", "permanent": true }
|
|
],
|
|
"rewrites": [
|
|
{ "source": "/docs/:match*", "destination": "https://worldmonitor.mintlify.dev/docs/:match*" },
|
|
{ "source": "/pro", "destination": "/pro/index.html" },
|
|
{ "source": "/mcp", "destination": "/api/mcp" },
|
|
{ "source": "/oauth/token", "destination": "/api/oauth/token" },
|
|
{ "source": "/oauth/register", "destination": "/api/oauth/register" },
|
|
{ "source": "/oauth/authorize", "destination": "/api/oauth/authorize" },
|
|
{ "source": "/.well-known/oauth-protected-resource", "destination": "/api/oauth-protected-resource" },
|
|
{ "source": "/((?!api|mcp|oauth|assets|blog|docs|favico|map-styles|data|textures|pro|sw\\.js|workbox-[a-f0-9]+\\.js|manifest\\.webmanifest|offline\\.html|robots\\.txt|sitemap\\.xml|llms\\.txt|llms-full\\.txt|openapi\\.yaml|\\.well-known|wm-widget-sandbox\\.html).*)", "destination": "/index.html" }
|
|
],
|
|
"headers": [
|
|
{
|
|
"source": "/api/(.*)",
|
|
"headers": [
|
|
{ "key": "Access-Control-Allow-Origin", "value": "*" },
|
|
{ "key": "Access-Control-Allow-Methods", "value": "GET, POST, OPTIONS" },
|
|
{ "key": "Access-Control-Allow-Headers", "value": "Content-Type, Authorization, X-WorldMonitor-Key, X-Widget-Key, X-Pro-Key" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/mcp",
|
|
"headers": [
|
|
{ "key": "Access-Control-Allow-Origin", "value": "*" },
|
|
{ "key": "Access-Control-Allow-Methods", "value": "GET, POST, OPTIONS" },
|
|
{ "key": "Access-Control-Allow-Headers", "value": "Content-Type, Authorization, X-WorldMonitor-Key" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/oauth/(.*)",
|
|
"headers": [
|
|
{ "key": "Access-Control-Allow-Origin", "value": "*" },
|
|
{ "key": "Access-Control-Allow-Methods", "value": "GET, POST, OPTIONS" },
|
|
{ "key": "Access-Control-Allow-Headers", "value": "Content-Type, Authorization" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/.well-known/oauth-authorization-server",
|
|
"headers": [
|
|
{ "key": "Content-Type", "value": "application/json" },
|
|
{ "key": "Access-Control-Allow-Origin", "value": "*" },
|
|
{ "key": "Cache-Control", "value": "public, max-age=3600" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/.well-known/api-catalog",
|
|
"headers": [
|
|
{ "key": "Content-Type", "value": "application/linkset+json" },
|
|
{ "key": "Access-Control-Allow-Origin", "value": "*" },
|
|
{ "key": "Cache-Control", "value": "public, max-age=3600" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/.well-known/(.*)",
|
|
"headers": [
|
|
{ "key": "Access-Control-Allow-Origin", "value": "*" },
|
|
{ "key": "Cache-Control", "value": "public, max-age=3600" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/openapi.yaml",
|
|
"headers": [
|
|
{ "key": "Content-Type", "value": "application/yaml; charset=utf-8" },
|
|
{ "key": "Access-Control-Allow-Origin", "value": "*" },
|
|
{ "key": "Cache-Control", "value": "public, max-age=3600" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/docs/:path*",
|
|
"headers": [
|
|
{ "key": "X-Content-Type-Options", "value": "nosniff" },
|
|
{ "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains; preload" },
|
|
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/((?!docs).*)",
|
|
"headers": [
|
|
{ "key": "X-Content-Type-Options", "value": "nosniff" },
|
|
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
|
|
{ "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains; preload" },
|
|
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
|
|
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=(self), accelerometer=(), autoplay=(self \"https://www.youtube.com\" \"https://www.youtube-nocookie.com\"), bluetooth=(), display-capture=(), encrypted-media=(self \"https://www.youtube.com\" \"https://www.youtube-nocookie.com\"), gyroscope=(), hid=(), idle-detection=(), magnetometer=(), midi=(), payment=(self \"https://checkout.dodopayments.com\" \"https://test.checkout.dodopayments.com\" \"https://pay.google.com\" \"https://hooks.stripe.com\" \"https://js.stripe.com\"), picture-in-picture=(self \"https://www.youtube.com\" \"https://www.youtube-nocookie.com\" \"https://challenges.cloudflare.com\"), screen-wake-lock=(), serial=(), usb=(), xr-spatial-tracking=(\"https://challenges.cloudflare.com\")" },
|
|
{ "key": "Content-Security-Policy", "value": "default-src 'self'; connect-src 'self' https: wss: blob: data: https://*.ingest.sentry.io https://*.ingest.us.sentry.io; img-src 'self' data: blob: https:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' 'sha256-LnMFPWZxTgVOr2VYwIh9mhQ3l/l3+a3SfNOLERnuHfY=' 'sha256-4Z2xtr1B9QQugoojE/nbpOViG+8l2B7CZVlKgC78AeQ=' 'sha256-903UI9my1I7mqHoiVeZSc56yd50YoRJTB2269QqL76w=' 'sha256-EytE6o1N8rwzpVFMrF+WvBZr2y5UhFLw79o1/4VqS0s=' 'wasm-unsafe-eval' https://www.youtube.com https://static.cloudflareinsights.com https://vercel.live https://challenges.cloudflare.com https://*.clerk.accounts.dev https://abacus.worldmonitor.app https://*.dodopayments.com https://js.stripe.com; worker-src 'self' blob:; font-src 'self' data: https:; media-src 'self' data: blob: https:; frame-src 'self' https://worldmonitor.app https://tech.worldmonitor.app https://finance.worldmonitor.app https://commodity.worldmonitor.app https://happy.worldmonitor.app https://energy.worldmonitor.app https://www.youtube.com https://www.youtube-nocookie.com https://www.google.com https://webcams.windy.com https://challenges.cloudflare.com https://*.clerk.accounts.dev https://vercel.live https://*.vercel.app https://*.dodopayments.com https://pay.google.com https://hooks.stripe.com https://js.stripe.com; frame-ancestors 'self' https://www.worldmonitor.app https://tech.worldmonitor.app https://finance.worldmonitor.app https://commodity.worldmonitor.app https://happy.worldmonitor.app https://energy.worldmonitor.app https://worldmonitor.app https://vercel.live https://*.vercel.app; base-uri 'self'; object-src 'none'; form-action 'self' https://api.worldmonitor.app" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/api/slack/oauth/callback",
|
|
"headers": [
|
|
{ "key": "Content-Security-Policy", "value": "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline';" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/api/discord/oauth/callback",
|
|
"headers": [
|
|
{ "key": "Content-Security-Policy", "value": "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline';" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/api/brief/(.*)",
|
|
"headers": [
|
|
{ "key": "Content-Security-Policy", "value": "default-src 'self'; script-src 'self' 'unsafe-inline' https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' data: https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self' https://cloudflareinsights.com; frame-ancestors 'self' https://www.worldmonitor.app https://worldmonitor.app; base-uri 'self'; object-src 'none'; form-action 'none'" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "no-cache, no-store, must-revalidate" },
|
|
{ "key": "Link", "value": "</.well-known/api-catalog>; rel=\"api-catalog\"; type=\"application/linkset+json\", </openapi.yaml>; rel=\"service-desc\"; type=\"application/vnd.oai.openapi\", </docs/documentation>; rel=\"service-doc\"; type=\"text/html\", </api/health>; rel=\"status\"; type=\"application/json\", </.well-known/oauth-protected-resource>; rel=\"http://www.iana.org/assignments/relation/oauth-protected-resource\", </.well-known/oauth-authorization-server>; rel=\"http://www.iana.org/assignments/relation/oauth-authorization-server\", </.well-known/mcp/server-card.json>; rel=\"mcp-server-card\"; anchor=\"/mcp\", </.well-known/agent-skills/index.json>; rel=\"agent-skills-index\"; type=\"application/json\"" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/index.html",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "no-cache, no-store, must-revalidate" },
|
|
{ "key": "Link", "value": "</.well-known/api-catalog>; rel=\"api-catalog\"; type=\"application/linkset+json\", </openapi.yaml>; rel=\"service-desc\"; type=\"application/vnd.oai.openapi\", </docs/documentation>; rel=\"service-doc\"; type=\"text/html\", </api/health>; rel=\"status\"; type=\"application/json\", </.well-known/oauth-protected-resource>; rel=\"http://www.iana.org/assignments/relation/oauth-protected-resource\", </.well-known/oauth-authorization-server>; rel=\"http://www.iana.org/assignments/relation/oauth-authorization-server\", </.well-known/mcp/server-card.json>; rel=\"mcp-server-card\"; anchor=\"/mcp\", </.well-known/agent-skills/index.json>; rel=\"agent-skills-index\"; type=\"application/json\"" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/((?!api|mcp|oauth|assets|blog|docs|favico|map-styles|data|textures|pro|sw\\.js|workbox-[a-f0-9]+\\.js|manifest\\.webmanifest|offline\\.html|robots\\.txt|sitemap\\.xml|llms\\.txt|llms-full\\.txt|openapi\\.yaml|\\.well-known|wm-widget-sandbox\\.html).*)",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "no-cache, no-store, must-revalidate" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/assets/(.*)",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/blog/_astro/(.*)",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/pro/assets/(.*)",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/pro/:path*",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "no-cache, no-store, must-revalidate" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/pro",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "no-cache, no-store, must-revalidate" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/favico/(.*)",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=604800" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/map-styles/(.*)",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/data/(.*)",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/textures/(.*)",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/offline.html",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=86400" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/workbox-:hash.js",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/sw.js",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=0, must-revalidate" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/manifest.webmanifest",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "public, max-age=86400" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/wm-widget-sandbox.html",
|
|
"headers": [
|
|
{ "key": "Content-Security-Policy", "value": "default-src 'none'; script-src 'unsafe-inline' https://cdn.jsdelivr.net https://static.cloudflareinsights.com; style-src 'unsafe-inline'; img-src data:; connect-src https://cdn.jsdelivr.net;" },
|
|
{ "key": "Cache-Control", "value": "public, max-age=86400" }
|
|
]
|
|
}
|
|
]
|
|
}
|