// load.ziran.space (docs/WEB-APP.md, Phase C): the hosted twin of the // desktop's embedded tile server (src/server/tileserver.ts). It serves ONLY // the fixed loader runtime — shuttle, worker, and the tiles-protocols // modules — on per-document origins under *.load.ziran.space; tile content // itself travels mothership → shuttle over postMessage and never touches // this server. No state, no secrets, nothing to lose. // // The app mints deterministic per-doc subdomains (t-.load.ziran.space) // rather than the stock random-per-load ones: with on-demand TLS a fresh // hostname per load would mint a fresh certificate per document open, which // is a Let's Encrypt rate-limit incident waiting to happen. Per-doc hosts // keep isolation at the same granularity the desktop has, bound the // certificate count, and let the worker's caches persist per document. // (A DNS-01 wildcard certificate is the recorded pre-beta follow-up.) import { readFile } from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; import express from 'express'; import { createTileLoadingRouter } from '@dasl/tile-server'; const PORT = Number(process.env.PORT ?? 3080); const LOAD_HOST = process.env.LOAD_HOST ?? 'load.ziran.space'; const TILE_HEADERS = { 'service-worker-allowed': '/', 'origin-agent-cluster': '?1', 'referrer-policy': 'no-referrer', 'permissions-policy': 'interest-cohort=(), browsing-topics=()', 'cross-origin-resource-policy': 'cross-origin', 'cross-origin-opener-policy': 'same-origin', 'x-content-type-options': 'nosniff', 'x-dns-prefetch-control': 'off', 'content-security-policy': [ `default-src 'self' blob: data:`, `script-src 'self' blob: data: 'unsafe-inline' 'wasm-unsafe-eval'`, `script-src-attr 'none'`, `style-src 'self' blob: data: 'unsafe-inline'`, `form-src 'self'`, `manifest-src 'none'`, `object-src 'none'`, `base-uri 'none'`, 'sandbox allow-downloads allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts', ].join('; '), 'tk': 'N', 'x-robots-tag': 'noai, noimageai', }; // Same override the desktop applies: shuttle.js/data.js ride ahead of the // npm tile-server release (tiles-protocols support), and store.js/sync.js/ // mode.js are ziran's own protocol modules tiles import from the runtime // path. Staged into ./vendor by `deno task stage:load` from the repo's // vendor/web-tiles — delete the override when a tile-server release ships // the protocol files. const VENDORED = new Set(['shuttle.js', 'data.js', 'store.js', 'sync.js', 'mode.js']); const vendorRoot = new URL('./vendor/', import.meta.url); const app = express(); app.set('trust proxy', true); // behind the supramundane front app.disable('x-powered-by'); // The front's generic nice-headers snippet is OFF for this service // ("headers": false): its X-Frame-Options sameorigin would forbid the very // framing this server exists for, and its other headers duplicated (and // contradicted) the hardened set below. HSTS was the one generic header // worth keeping — set it here, on everything. app.use((_req, res, next) => { res.set('strict-transport-security', 'max-age=63072000; preload'); next(); }); app.get('/health', (_req, res) => res.json({ ok: true })); // A manual visit to the bare load host gets bounced onto a random origin, // mirroring the stock router's own entry behavior (which expects to trigger // on `load.` — one level deeper than our layout). const LETTERS = 'abcdefghijklmnopqrstuvwxyz'; const randomSub = () => Array.from(crypto.getRandomValues(new Uint8Array(20)), (b) => LETTERS[b % LETTERS.length]).join(''); app.use((req, res, next) => { if (req.hostname === LOAD_HOST) { res.redirect(303, `https://${randomSub()}.${LOAD_HOST}${req.originalUrl || '/'}`); return; } next(); }); app.use('/.well-known/web-tiles', async (req, res, next) => { const name = req.path.replace(/^\//, ''); if (!VENDORED.has(name)) return next(); try { const bytes = await readFile(new URL(name, vendorRoot)); res.set(TILE_HEADERS); res.type('text/javascript'); res.end(bytes); } catch (err) { console.error(`vendored ${name} missing:`, err.message); next(); } }); app.use(createTileLoadingRouter(LOAD_HOST)); app.listen(PORT, '0.0.0.0', () => { console.log(`ziran-load: serving the tile runtime for *.${LOAD_HOST} on :${PORT} (vendor at ${fileURLToPath(vendorRoot)})`); });