SkateSpots/index.html

94 lines
4.8 KiB
HTML

<!DOCTYPE html>
<html lang="en" style="background:#050505">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<title>SkateSpots - Decentralized Skate Map &amp; Community</title>
<!--
Content-Security-Policy (defense-in-depth) — shipped in the HTML so it
applies to BOTH the web build AND the native Capacitor build.
Why a <meta> tag and not just HTTP headers: Capacitor loads the bundle
from a local scheme (https://localhost on Android, capacitor://localhost
on iOS), so the server headers in public/_headers / netlify.toml never
reach the mobile WebView. The OS sandbox isolates the app from OTHER apps;
it does NOT stop a same-origin injected script from reading this app's own
IndexedDB (Cashu ecash proofs) or localStorage (nsec, NWC string, Cashu
seed). A CSP is therefore just as important on mobile as on web.
Capacitor's local origins/schemes are allowlisted below so asset loading,
the local dev server, and live-reload continue to work. Notably there is
no 'unsafe-inline'/'unsafe-eval' on script-src (only 'wasm-unsafe-eval'
for the Bitcoin/Cashu WASM), which is the directive that actually blocks
injected <script>/onerror payloads. Keep this in sync with
public/_headers and netlify.toml.
-->
<meta http-equiv="Content-Security-Policy" content="
default-src 'none';
script-src 'self' 'wasm-unsafe-eval' https://localhost capacitor://localhost ionic://localhost;
style-src 'self' 'unsafe-inline' https://localhost capacitor://localhost ionic://localhost;
img-src 'self' data: blob: https: https://localhost capacitor://localhost ionic://localhost;
font-src 'self' data: https://fonts.gstatic.com;
connect-src 'self' https: wss: https://localhost capacitor://localhost ionic://localhost;
media-src 'self' blob: https:;
frame-src 'self' https:;
worker-src 'self' blob:;
manifest-src 'self';
object-src 'none';
base-uri 'none';
form-action 'self'
">
<!-- PWA Manifest -->
<link rel="manifest" href="/manifest.webmanifest">
<!-- App Icons -->
<link rel="icon" type="image/png" href="/images/icon-1024.png">
<link rel="apple-touch-icon" href="/images/icon-1024.png">
<link rel="apple-touch-icon" sizes="152x152" href="/images/icon-1024.png">
<link rel="apple-touch-icon" sizes="180x180" href="/images/icon-1024.png">
<link rel="apple-touch-startup-image" href="/images/icon-1024.png">
<!-- Theme Color -->
<meta name="theme-color" content="#ff0040">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="SkateSpots">
<!-- SEO Meta Tags -->
<meta name="description" content="Discover skate spots, find coaches, join events, and connect with the skateboarding community on Nostr. Free, decentralized, censorship-resistant.">
<meta name="keywords" content="skateboarding, skate spots, skate parks, nostr, decentralized, bitcoin, lightning, zaps">
<!-- Open Graph -->
<meta property="og:type" content="website">
<meta property="og:title" content="SkateSpots - Decentralized Skate Map & Community">
<meta property="og:description" content="Discover skate spots, find coaches, join events, and connect with the skateboarding community on Nostr.">
<meta property="og:image" content="https://skate-spots.org/images/icon-1024.png">
<meta property="og:url" content="https://skate-spots.org">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="SkateSpots - Decentralized Skate Map">
<meta name="twitter:description" content="Discover skate spots, find coaches, join events on Nostr.">
<meta name="twitter:image" content="https://skate-spots.org/images/icon-1024.png">
<!-- Leaflet CSS is self-hosted (imported in main.tsx) — no unpkg/CDN. -->
<!-- Warm up the connections used on almost every visit: our relay + media. -->
<link rel="dns-prefetch" href="https://relay.skate-spots.org">
<link rel="dns-prefetch" href="https://blossom.skate-spots.org">
<link rel="preconnect" href="https://relay.skate-spots.org" crossorigin>
<link rel="preconnect" href="https://blossom.skate-spots.org" crossorigin>
</head>
<body style="background:#050505">
<div id="root"></div>
<!--
BOOT CRASH GUARD (native-safe) — external so the web build can ship a
strict CSP (script-src 'self') with no 'unsafe-inline'. See boot-guard.js.
-->
<script src="/boot-guard.js?v=20261030"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>