From 08034c4402e56ae597846c7555bd43bff4287df7 Mon Sep 17 00:00:00 2001 From: Maurice Date: Tue, 10 Nov 2026 09:17:25 +0100 Subject: [PATCH] fix(map): the iOS app's tile store is allowed by the CSP, so its maps draw tiles again The iOS app rewrites raster tiles to trek-tile:// and answers them from its store. WebKit checks that scheme against img-src, which had only https:, so every tile was refused and the app showed routes and markers on a blank map. --- server/src/middleware/globalMiddleware.ts | 6 +++++- server/tests/unit/middleware/globalMiddleware.csp.test.ts | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/server/src/middleware/globalMiddleware.ts b/server/src/middleware/globalMiddleware.ts index c150b0661..b05066fb2 100644 --- a/server/src/middleware/globalMiddleware.ts +++ b/server/src/middleware/globalMiddleware.ts @@ -280,7 +280,11 @@ export function applyGlobalMiddleware( scriptSrc: ["'self'", "'wasm-unsafe-eval'", "'unsafe-eval'"], // No Google Fonts: every font ships with TREK (client/public/fonts), so no reader's IP goes to Google. styleSrc: ["'self'", "'unsafe-inline'", 'https://unpkg.com'], - imgSrc: ["'self'", 'data:', 'blob:', 'https:'], + // trek-tile: is the iOS app's map tile store (client/src/native/tileCache.ts). + // The app's web view runs this page, and WebKit holds a scheme the app + // answers itself to img-src as well: without it every raster tile was + // refused and the app showed routes on a blank map. + imgSrc: ["'self'", 'data:', 'blob:', 'https:', 'trek-tile:'], connectSrc: [ "'self'", 'ws:', diff --git a/server/tests/unit/middleware/globalMiddleware.csp.test.ts b/server/tests/unit/middleware/globalMiddleware.csp.test.ts index 4dd6a3995..47f10d691 100644 --- a/server/tests/unit/middleware/globalMiddleware.csp.test.ts +++ b/server/tests/unit/middleware/globalMiddleware.csp.test.ts @@ -114,6 +114,14 @@ describe('global CSP: the imagery host (#2307)', () => { }); }); +describe('global CSP: the iOS app tile store', () => { + it('allows trek-tile: images, or the app draws routes on a blank map', async () => { + // The app rewrites raster tiles to trek-tile:// (client/src/native/tileCache.ts) + // and answers them from its store; WebKit checks that scheme against img-src. + expect(await directiveSources('img-src')).toContain('trek-tile:'); + }); +}); + describe('global CSP: the elevation tiles of the 3D tour view', () => { it('allows the Terrarium tiles, which MapLibre and the flyover preload fetch', async () => { // The 3D view drapes the route over Mapzen's open elevation model on AWS Open