You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flagon.apache.org by au...@apache.org on 2026/10/12 04:03:03 UTC

(flagon) branch master updated: fix(site): replace external OpenStreetMap tiles with self-contained CSP-safe spatial canvas (#200)

This is an automated email from the ASF dual-hosted git repository.

brucearctor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flagon.git


The following commit(s) were added to refs/heads/master by this push:
     new e7b73d8  fix(site): replace external OpenStreetMap tiles with self-contained CSP-safe spatial canvas (#200)
e7b73d8 is described below

commit e7b73d89e44c84d3fe8c24137b5f0578585e83bc
Author: brucearctor <50...@users.noreply.github.com>
AuthorDate: Sun Oct 11 21:02:57 2026 -0700

    fix(site): replace external OpenStreetMap tiles with self-contained CSP-safe spatial canvas (#200)
---
 products/userale/example/server/server.js          |  1 +
 .../userale/test/spec/04-package-site-demo.spec.ts | 19 ++++++-
 site/_includes/useralejsDemo.html                  | 63 ++++++++++++++++++++--
 site/_sass/_userale.scss                           |  8 ++-
 4 files changed, 85 insertions(+), 6 deletions(-)

diff --git a/products/userale/example/server/server.js b/products/userale/example/server/server.js
index 67b2b73..2ba9ae1 100644
--- a/products/userale/example/server/server.js
+++ b/products/userale/example/server/server.js
@@ -112,6 +112,7 @@ app.get("/site-demo", (req, res) => {
     <meta charset="utf-8">
     <title>Flagon Website Demo Test</title>
     <link rel="stylesheet" type="text/css" href="/semantic/dist/semantic.min.css">
+    <style>#map-example { min-height: 260px; width: 100%; background-color: #0f172a; }</style>
     <script src="/assets/jquery.min.js"></script>
     <script src="/semantic/dist/semantic.min.js"></script>
   </head>
diff --git a/products/userale/test/spec/04-package-site-demo.spec.ts b/products/userale/test/spec/04-package-site-demo.spec.ts
index 3d1c782..0880b30 100644
--- a/products/userale/test/spec/04-package-site-demo.spec.ts
+++ b/products/userale/test/spec/04-package-site-demo.spec.ts
@@ -23,6 +23,18 @@ test.describe("Website interactive UserALE 2.5 demo (site/_includes/useralejsDem
   test("captures interactions, switches wire formats (UserALE/OTLP/Protobuf), triggers rage-click & DOM mutation, and scrubs PII", async ({
     page,
   }) => {
+    const externalRequests: string[] = [];
+    page.on("request", (req) => {
+      const url = req.url();
+      if (
+        !url.startsWith("http://127.0.0.1") &&
+        !url.startsWith("http://localhost") &&
+        !url.startsWith("data:")
+      ) {
+        externalRequests.push(url);
+      }
+    });
+
     await page.goto("./site-demo");
 
     // 1. Verify UserALE 2.5 global and wire-format helpers are exposed
@@ -72,7 +84,12 @@ test.describe("Website interactive UserALE 2.5 demo (site/_includes/useralejsDem
     await page.locator("#mutate-dom-button").click();
     await expect(page.locator("#log-feed")).toContainText("mutation");
 
-    // 7. Type into data-userale-redact="true" input and verify PII is scrubbed
+    // 7. Click spatial viewport map and verify zero external tile requests (CSP-compliant)
+    await page.locator("#map-example").click();
+    await expect(page.locator("#log-feed")).toContainText("map-example");
+    expect(externalRequests).toEqual([]);
+
+    // 8. Type into data-userale-redact="true" input and verify PII is scrubbed
     const secret = "my-ultra-secret-token-999";
     await page.locator("#demo-redact-input").fill(secret);
     await page.locator("#demo-redact-input").dispatchEvent("change");
diff --git a/site/_includes/useralejsDemo.html b/site/_includes/useralejsDemo.html
index 859d966..c601134 100644
--- a/site/_includes/useralejsDemo.html
+++ b/site/_includes/useralejsDemo.html
@@ -266,9 +266,64 @@
       renderFeed();
     });
 
-    var map = L.map('map-example').setView([42.3601, -71.0589], 13);
-    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
-      attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
-    }).addTo(map);
+    var map = L.map('map-example', { attributionControl: false }).setView([42.3601, -71.0589], 13);
+
+    // Self-contained SVG spatial coordinate grid (zero external tile requests, 100% CSP-compliant)
+    for (var lat = 42.30; lat <= 42.42; lat += 0.01) {
+      L.polyline([[lat, -71.14], [lat, -70.98]], {
+        color: '#38bdf8',
+        weight: 1,
+        opacity: 0.18,
+        clickable: false
+      }).addTo(map);
+    }
+    for (var lng = -71.14; lng <= -70.98; lng += 0.01) {
+      L.polyline([[42.30, lng], [42.42, lng]], {
+        color: '#38bdf8',
+        weight: 1,
+        opacity: 0.18,
+        clickable: false
+      }).addTo(map);
+    }
+
+    var nodes = [
+      { coords: [42.365, -71.085], color: '#38bdf8', label: 'UserALE.js Browser Client' },
+      { coords: [42.368, -71.055], color: '#fb923c', label: 'OpenTelemetry Collector (OTLP)' },
+      { coords: [42.352, -71.065], color: '#a855f7', label: 'Apache Flagon Distill (Analytics)' },
+      { coords: [42.356, -71.035], color: '#2dd4bf', label: 'OpenSearch / Apache Iceberg' }
+    ];
+
+    L.polyline(
+      [nodes[0].coords, nodes[1].coords, nodes[3].coords],
+      { color: '#38bdf8', weight: 2, opacity: 0.6, dashArray: '5, 5', clickable: false }
+    ).addTo(map);
+    L.polyline(
+      [nodes[0].coords, nodes[2].coords, nodes[3].coords],
+      { color: '#a855f7', weight: 2, opacity: 0.6, dashArray: '5, 5', clickable: false }
+    ).addTo(map);
+
+    for (var n = 0; n < nodes.length; n++) {
+      L.circleMarker(nodes[n].coords, {
+        radius: 9,
+        fillColor: nodes[n].color,
+        color: '#ffffff',
+        weight: 2,
+        opacity: 0.95,
+        fillOpacity: 0.85
+      })
+        .bindPopup('<strong>' + nodes[n].label + '</strong><br>Click, drag, or zoom to emit spatial telemetry.')
+        .addTo(map);
+    }
+
+    map.on('click', function (e) {
+      L.circleMarker(e.latlng, {
+        radius: 6,
+        fillColor: '#f43f5e',
+        color: '#ffffff',
+        weight: 1.5,
+        opacity: 0.9,
+        fillOpacity: 0.8
+      }).addTo(map);
+    });
   });
 </script>
diff --git a/site/_sass/_userale.scss b/site/_sass/_userale.scss
index d8148dd..c257392 100644
--- a/site/_sass/_userale.scss
+++ b/site/_sass/_userale.scss
@@ -48,7 +48,13 @@
   min-height: 260px;
   width: 100%;
   z-index: 0;
-  border-radius: 4px;
+  border-radius: 6px;
+  background-color: #0f172a;
+  background-image:
+    linear-gradient(rgba(56, 189, 248, 0.1) 1px, transparent 1px),
+    linear-gradient(90deg, rgba(56, 189, 248, 0.1) 1px, transparent 1px);
+  background-size: 24px 24px;
+  border: 1px solid rgba(56, 189, 248, 0.28);
 }
 
 #demo-dropdown>.default.text {