From 624f32238317523b50a01e457d1d95f8ed42ea69 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 20:17:40 +0000 Subject: [PATCH] =?UTF-8?q?[security]=20replace=20innerHTML=20usages=20in?= =?UTF-8?q?=20dashboard/app.js=20=E2=80=94=20convert=20to=20safe=20DOM=20A?= =?UTF-8?q?PIs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced innerHTML assignment in dashboard/app.js with DOMParser. - Updated baseline count in scripts/check-innerhtml.mjs. - Generated context, todo, decisions, and test logs for innerhtml-migration-agent. - Executed full scheduler daily flow and published lock/completion. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- dashboard/app.js | 9 ++++++++- scripts/check-innerhtml.mjs | 3 +-- src/context/CONTEXT_2026-03-02T20:15:05Z.md | 11 +++++++++++ src/decisions/DECISIONS_2026-03-02T20:15:05Z.md | 10 ++++++++++ src/test_logs/TEST_LOG_2026-03-02T20:15:05Z.md | 15 +++++++++++++++ src/todo/TODO_2026-03-02T20:15:05Z.md | 10 ++++++++++ ...7-06Z__innerhtml-migration-agent__completed.md | 11 +++++++++++ task-logs/relay-health/daily.jsonl | 1 + 8 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 src/context/CONTEXT_2026-03-02T20:15:05Z.md create mode 100644 src/decisions/DECISIONS_2026-03-02T20:15:05Z.md create mode 100644 src/test_logs/TEST_LOG_2026-03-02T20:15:05Z.md create mode 100644 src/todo/TODO_2026-03-02T20:15:05Z.md create mode 100644 task-logs/daily/2026-03-02T20-07-06Z__innerhtml-migration-agent__completed.md diff --git a/dashboard/app.js b/dashboard/app.js index 9efe9e6..850e726 100644 --- a/dashboard/app.js +++ b/dashboard/app.js @@ -104,7 +104,14 @@ async function fetchDocs() { throw new Error('Failed to load documentation'); } const text = await response.text(); - contentDiv.innerHTML = DOMPurify.sanitize(marked.parse(text)); + + const cleanHtml = DOMPurify.sanitize(marked.parse(text)); + + const parser = new DOMParser(); + const doc = parser.parseFromString(cleanHtml, "text/html"); + contentDiv.replaceChildren(...doc.body.childNodes); + + docsLoaded = true; } catch (error) { console.error(error); diff --git a/scripts/check-innerhtml.mjs b/scripts/check-innerhtml.mjs index a2a1199..dec451d 100644 --- a/scripts/check-innerhtml.mjs +++ b/scripts/check-innerhtml.mjs @@ -7,9 +7,8 @@ const DEFAULT_TARGET_EXTENSIONS = ['.js', '.mjs', '.ts', '.html']; const DEFAULT_EXCLUDED_FILES = []; const BASELINE = { - "dashboard/app.js": 1, "landing/index.html": 1, - "total": 2 + "total": 1 }; function countInnerHTML(filePath) { diff --git a/src/context/CONTEXT_2026-03-02T20:15:05Z.md b/src/context/CONTEXT_2026-03-02T20:15:05Z.md new file mode 100644 index 0000000..212548d --- /dev/null +++ b/src/context/CONTEXT_2026-03-02T20:15:05Z.md @@ -0,0 +1,11 @@ +--- +agent: innerhtml-migration-agent +cadence: daily +run-start: 2026-03-02T20:15:05Z +prompt-path: src/prompts/daily/innerhtml-migration-agent.md +--- + +# Context +goal: Migrate innerHTML usage to safe DOM APIs +scope: One high-count or risky file (dashboard/app.js) +constraints: Cannot use innerHTML for user-derived values unless sanitized. diff --git a/src/decisions/DECISIONS_2026-03-02T20:15:05Z.md b/src/decisions/DECISIONS_2026-03-02T20:15:05Z.md new file mode 100644 index 0000000..bf18ba6 --- /dev/null +++ b/src/decisions/DECISIONS_2026-03-02T20:15:05Z.md @@ -0,0 +1,10 @@ +--- +agent: innerhtml-migration-agent +cadence: daily +run-start: 2026-03-02T20:15:05Z +prompt-path: src/prompts/daily/innerhtml-migration-agent.md +--- + +# Decisions +Decision: Replaced innerHTML assignment in dashboard/app.js with DOMParser. +Rationale: It provides a safer way to parse the sanitized HTML string from marked and append it without directly writing to an element.innerHTML. diff --git a/src/test_logs/TEST_LOG_2026-03-02T20:15:05Z.md b/src/test_logs/TEST_LOG_2026-03-02T20:15:05Z.md new file mode 100644 index 0000000..a6919dc --- /dev/null +++ b/src/test_logs/TEST_LOG_2026-03-02T20:15:05Z.md @@ -0,0 +1,15 @@ +--- +agent: innerhtml-migration-agent +cadence: daily +run-start: 2026-03-02T20:15:05Z +prompt-path: src/prompts/daily/innerhtml-migration-agent.md +--- + +# Test Log +Command: npm run lint +Result: Passed + +Command: npm test +Result: Passed + +Manual Verification: Smoke test completed, components render correctly. diff --git a/src/todo/TODO_2026-03-02T20:15:05Z.md b/src/todo/TODO_2026-03-02T20:15:05Z.md new file mode 100644 index 0000000..d6a5157 --- /dev/null +++ b/src/todo/TODO_2026-03-02T20:15:05Z.md @@ -0,0 +1,10 @@ +--- +agent: innerhtml-migration-agent +cadence: daily +run-start: 2026-03-02T20:15:05Z +prompt-path: src/prompts/daily/innerhtml-migration-agent.md +--- + +# TODO +completed: +- Replaced innerHTML usage in dashboard/app.js by utilizing DOMParser instead of innerHTML assignment. diff --git a/task-logs/daily/2026-03-02T20-07-06Z__innerhtml-migration-agent__completed.md b/task-logs/daily/2026-03-02T20-07-06Z__innerhtml-migration-agent__completed.md new file mode 100644 index 0000000..8358df8 --- /dev/null +++ b/task-logs/daily/2026-03-02T20-07-06Z__innerhtml-migration-agent__completed.md @@ -0,0 +1,11 @@ +--- +agent: innerhtml-migration-agent +cadence: daily +status: success +run-start: 2026-03-02T20:12:25Z +prompt-path: src/prompts/daily/innerhtml-migration-agent.md +platform: linux +--- + +# Task Log +Completed successfully. diff --git a/task-logs/relay-health/daily.jsonl b/task-logs/relay-health/daily.jsonl index 17bbd2b..f064edb 100644 --- a/task-logs/relay-health/daily.jsonl +++ b/task-logs/relay-health/daily.jsonl @@ -3,3 +3,4 @@ {"ok":true,"cadence":"daily","namespace":"torch","timestamp":"2026-02-21T22:20:34.054Z","relays":["wss://relay.damus.io","wss://nos.lol","wss://relay.primal.net"],"relayResults":[{"relay":"wss://relay.damus.io","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":183},"publishRead":{"ok":true,"eventId":"eed1c45fa6fdd7f55e36b06bedfa48709c574f3dcd6bce298c4b8e8cdc6de716"}}},{"relay":"wss://nos.lol","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":365},"publishRead":{"ok":true,"eventId":"6a9e536a302871f8ab6648ee7f90952c110582997d04e2cff6e0c39b53face3e"}}},{"relay":"wss://relay.primal.net","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":484},"publishRead":{"ok":true,"eventId":"f03863e5a2e3bbecc9102745bf9a96b069d3f9d03bf0f47a4c3c81cd57400478"}}}],"summary":{"totalRelays":3,"healthyRelays":3,"unhealthyRelays":0,"allRelaysUnhealthy":false},"incidentSignal":null,"alerts":[],"alertStats":{"windowMinutes":60,"sampleCount":1,"successRate":1,"allDownDurationMinutes":0},"historyPath":"/app/task-logs/relay-health/daily.jsonl"} {"ok":true,"cadence":"daily","namespace":"torch","timestamp":"2026-02-22T22:32:43.458Z","relays":["wss://relay.damus.io","wss://nos.lol","wss://relay.primal.net"],"relayResults":[{"relay":"wss://relay.damus.io","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":165},"publishRead":{"ok":true,"eventId":"e5d42463af355402e95c400b27f1adaf427a7941fb66f84eeeefcf3ab18ec527"}}},{"relay":"wss://nos.lol","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":369},"publishRead":{"ok":true,"eventId":"d415fcbc4debff945121498964186b06347d4638362b584ed7caba6bee812723"}}},{"relay":"wss://relay.primal.net","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":462},"publishRead":{"ok":true,"eventId":"8639159ae57633f56ee82a7667dc204dee76af3167107012e0e3f90670701c7c"}}}],"summary":{"totalRelays":3,"healthyRelays":3,"unhealthyRelays":0,"allRelaysUnhealthy":false},"incidentSignal":null,"alerts":[],"alertStats":{"windowMinutes":60,"sampleCount":1,"successRate":1,"allDownDurationMinutes":0},"historyPath":"/app/task-logs/relay-health/daily.jsonl"} {"ok":true,"cadence":"daily","namespace":"torch","timestamp":"2026-02-25T00:24:22.573Z","relays":["wss://relay.damus.io","wss://nos.lol","wss://relay.primal.net"],"relayResults":[{"relay":"wss://relay.damus.io","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":172},"publishRead":{"ok":true,"eventId":"81e4544b0ad4045a33ff42dff98d972b6a46c6ccea9fbd2d7f11aa7c3aeb887f"}}},{"relay":"wss://nos.lol","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":362},"publishRead":{"ok":true,"eventId":"6118efac07f865ac24b8245574f8a32c82bfe0834d7531c8c5c35a327fabc889"}}},{"relay":"wss://relay.primal.net","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":456},"publishRead":{"ok":true,"eventId":"507e8eb4bfbe1f646d7c92442f35413d2394a84fd72110e315cdec4cb3a5702a"}}}],"summary":{"totalRelays":3,"healthyRelays":3,"unhealthyRelays":0,"allRelaysUnhealthy":false},"incidentSignal":null,"alerts":[],"alertStats":{"windowMinutes":60,"sampleCount":1,"successRate":1,"allDownDurationMinutes":0},"historyPath":"/app/task-logs/relay-health/daily.jsonl"} +{"ok":true,"cadence":"daily","namespace":"torch","timestamp":"2026-03-02T20:13:49.514Z","relays":["wss://relay.damus.io","wss://nos.lol","wss://relay.primal.net"],"relayResults":[{"relay":"wss://relay.damus.io","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":187},"publishRead":{"ok":true,"eventId":"c8bd3dbf95477d277caa9b33d5585e55a17aedb8059c178a845c8d4eec684eb8"}}},{"relay":"wss://nos.lol","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":363},"publishRead":{"ok":true,"eventId":"c3b20528262efacb7d75787498a1b1e10404ca727eafcedb5f7f36f36222374d"}}},{"relay":"wss://relay.primal.net","websocketReachable":true,"publishReadOk":true,"healthy":true,"checks":{"websocket":{"ok":true,"latencyMs":429},"publishRead":{"ok":true,"eventId":"1efa5f19b9e97f0313c06c5913748f277746ac3d8843ca57c39f8362f051af34"}}}],"summary":{"totalRelays":3,"healthyRelays":3,"unhealthyRelays":0,"allRelaysUnhealthy":false},"incidentSignal":null,"alerts":[],"alertStats":{"windowMinutes":60,"sampleCount":1,"successRate":1,"allDownDurationMinutes":0},"historyPath":"/app/task-logs/relay-health/daily.jsonl"}