19-Apr-2026 — centralise worker secrets, harden paste flows, and bypass headless-bot detection

build 615commit b70e39a


Centralise worker wiring in Global Application Secrets

INTEGRATION_WORKER_URL, INTEGRATION_WORKER_SHARED_SECRET and INTEGRATION_WORKER_ENCRYPTION_KEY are the same value for every env — they belong in the root config.environments.value.secrets section (the Global Application Secrets panel in Admin), not sprinkled across each environments[].secrets. buildSecretsFromDatabaseConfig already merges root secrets into every env deploy, so no code change is needed for the shared trio to propagate.

INTEGRATION_WORKER_CALLBACK_BASE_URL genuinely differs per env (each website has its own fly URL). Auto-derive it in buildSecretsFromDatabaseConfig from envConfig.flyio.appName when no explicit value is set, so any new env is worker-ready on first deploy without manual per-env secret curation.

Data already migrated in staging DB: three shared keys added under globals; staging, ekwg, ekwg-dev-2-staging per-env duplicates removed. Each now only carries INTEGRATION_WORKER_CALLBACK_BASE_URL.

Paste-URL hardening (CMS dynamic content text field)

isBase64Image at url.service.ts already accepts any data: URI (fixes GIF preview GET /api/aws/s3/data:image/... errors), and the image cropper enables save for non-croppable files (GIFs) with awsFileName falling back to originalFile.name.

PageContentService.allAlbumIndexParents now returns early for an undefined childPath (happens during initial CMS page load before pageContent resolves) and guards against non-string contentPath values with isString from es-toolkit/compat, fixing TypeError: Cannot read properties of undefined (reading 'startsWith') reported in the dynamic content editor.

Worker browser fingerprint

integration-worker-browser-routes now creates pages via a browser.newContext({ userAgent, viewport, locale, timezoneId, extraHTTPHeaders }) helper rather than browser.newPage() directly, so sites behind Cloudflare/Akamai (e.g. ramblers.org.uk) don't serve 403 Forbidden on fingerprint. Applied to both html-fetch and flickr-user-albums routes.

Misc

navigate-with-dom-loaded task added in the previous commit is used declaratively from walks-upload.ts; removed the explanatory comment block to comply with the project's no-comments rule.