From 203ca5bc4df8cc6ea5f19c0a84b0dba09170c1bf Mon Sep 17 00:00:00 2001 From: ekke Date: Tue, 23 Jun 2026 13:16:37 +0000 Subject: [PATCH] Permit-iframe hardening, import UX refinements, workshop deliverables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Permit-iframe hardening: - public/embed.php — replace the 302 redirect on unauthenticated visits with an in-iframe HTML "Sign in to view the map" card (HTTP 401) whose primary button uses target="_top" to break the iframe and send the parent window to the SSO portal. The 302 was broken UX inside an iframe because the LUSPA portal refuses to be framed. - public/embed.php + public/.htaccess — strip X-Frame-Options at the embed endpoint (defence in depth). Apache's Header always unset X-Frame-Options + PHP's header_remove() both ensure the only iframe-policy header on the response is our CSP frame-ancestors (which already allows the permits subdomain). Fixes Safari's "Refused to display ... because it set 'X-Frame-Options' to 'SAMEORIGIN'" when the container's reverse proxy injects it. Import UX refinements: - Spinner overlay (index.html #import-spinner-overlay + main.js showImportSpinner/hideImportSpinner) shown during the file-drop → mapping-modal gap. Wired at the top of each handle*Import and at every error / early-return path; hidden by stageImport() just before openImportMappingModal() so it spans both the JS parse and the SQLocal staging insert. - Per-feature client_uuid tagging — each imported OL feature now carries _externalImportId + _clientUuid set in stageImport(). These tags are the link that lets later edits find the matching staging row, and they are passed through to addExternalImportFeatures. - Geometry-edit persistence — new public callback registry MapView.onFeatureModified(cb) fired from a modifyend listener on _modifyInteraction. main.js handler writes the new WKT (EPSG:4326) back to external_import_features.geometry_wkt via new helper updateExternalImportFeatureGeometry(clientUuid, wkt). Non-imported features carry no tags, so the handler is a no-op for them. - Delete persistence — removefeature listener on each imported layer's source. New helper deleteExternalImportFeature(clientUuid) runs an atomic DELETE + decrement of external_imports.feature_count and broadcasts the changes so the LayerSwitcher badge can recount. - Field-mapping dropdown — sample values + bold field names. New helpers sampleSourceValues(fc) in import-detect.js (picks first non-empty value per attribute, JSON-stringifies objects, collapses whitespace, truncates to 35 chars) and toBoldUnicode(s) in import-modal.js (ASCII letters/digits → Mathematical Alphanumeric Symbols block). Options now read as "𝐮𝐩𝐧 — [12345-6789]"; HTML/CSS bold doesn't render inside