From e6c5198caacdb5c4b2f7a0719af4fbba9451ac49 Mon Sep 17 00:00:00 2001 From: Ilia Denisov Date: Wed, 1 Jul 2026 16:57:05 +0200 Subject: [PATCH] build(ui): drop sourcemaps from prod bundle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The production UI build shipped `.map` files with full `sourcesContent`, and the gateway/landing images serve `dist/` verbatim, so anyone could fetch `/app/assets/main-*.js.map` (same assets under `/vk/`, `/telegram/`) and reconstruct the entire TypeScript/Svelte source at the edge. Gate `build.sourcemap` off for `mode === 'production'` (the Docker image build). Dev and the `mock` e2e build (`vite build --mode mock`) keep maps for debugging. Document the posture in ARCHITECTURE.md ยง12. --- docs/ARCHITECTURE.md | 7 +++++++ ui/vite.config.ts | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 153de12..8bbf8c6 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1055,6 +1055,13 @@ valid-code population). Brute-forcing a 6-digit friend code within these limits accepted MVP risk with low blast radius (an unwanted friendship is removable/blockable); a dedicated redeem sub-limit or a longer code is the hardening step if abuse appears. +**Client source exposure.** The production UI build ships **no sourcemaps** +(`vite.config.ts` gates `build.sourcemap` off when `mode === 'production'`), so the gateway +and landing images serve only minified JS and the full TypeScript/Svelte source is not +recoverable from a served `.map` at the edge. Dev and the `mock` e2e build (`vite build +--mode mock`) keep maps for debugging. This is surface reduction, not secrecy โ€” the single +minified bundle still carries all platform code paths and is reversible with effort. + ## 13. Deployment (informational) Single public origin, path-routed. The Vite build has two entries: a lightweight diff --git a/ui/vite.config.ts b/ui/vite.config.ts index 7a26d40..53258e6 100644 --- a/ui/vite.config.ts +++ b/ui/vite.config.ts @@ -34,7 +34,13 @@ export default defineConfig(({ mode }) => ({ }, build: { target: 'es2022', - sourcemap: true, + // Emit sourcemaps everywhere except the production build. A shipped `.map` + // carries full `sourcesContent` โ€” the entire TypeScript/Svelte source โ€” and the + // gateway/landing images serve `dist/` verbatim, so production maps would expose + // the whole client source at the edge. Dev and the `mock` e2e build + // (`vite build --mode mock`) keep maps for debugging; the production `vite build` + // (the Docker image build) drops them. + sourcemap: mode !== 'production', // Two entries: the game SPA (index.html, served at /app/ + /telegram/) and the // public landing page (landing.html, served at /). Assets are shared in dist/assets/, and // the relative base lets one build serve under any path.