Skip to content

fix(deps): resolve high-severity prod audit advisories (hono, protobufjs)#178

Open
ankitvgupta wants to merge 1 commit into
mainfrom
ankitvgupta/muscat
Open

fix(deps): resolve high-severity prod audit advisories (hono, protobufjs)#178
ankitvgupta wants to merge 1 commit into
mainfrom
ankitvgupta/muscat

Conversation

@ankitvgupta

@ankitvgupta ankitvgupta commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes #176. The Security Audit CI job (npm audit --omit=dev --audit-level=high) was failing on every PR due to pre-existing high-severity advisories in the production dependency tree (hono, protobufjs). A perpetually-red check desensitizes reviewers and can mask a genuinely new vulnerability.

This is a scoped, in-range, lockfile-only fix — package.json is unchanged (no dependency range changes, no breaking majors). After it, npm audit --omit=dev reports 0 vulnerabilities across all severities (not just the highs).

Changes (package-lock.json only)

Package Old → New Severity Notes
hono 4.12.18 → 4.12.25 HIGH transitive via @modelcontextprotocol/sdk; fixes CORS/cookie/JWT/path-traversal advisories
protobufjs removed HIGH orphaned & dropped (see posthog-js)
posthog-js 1.364.1 → 1.387.0 newer posthog-js no longer depends on the @opentelemetry/* OTLP log-exporter chain → removes protobufjs (HIGH) + the @opentelemetry/core moderates entirely
dompurify 3.4.0 → 3.4.10 moderate XSS hardening (IN_PLACE/addHook/Trusted-Types edge cases)
js-yaml 4.1.1 → 4.2.0 moderate merge-key DoS
markdown-it 14.1.1 → 14.2.0 moderate smartquotes DoS (transitive via Tiptap)
nodemailer 8.0.5 → 8.0.11 moderate CRLF header-injection + TLS-cert-validation (in-range 8.0.x maintenance line)
qs 6.15.0 → 6.15.2 moderate qs.stringify DoS

Net diff: 64 insertions / 380 deletions — the bulk is the removed, unused @opentelemetry/* + @protobufjs/* subtree.

Why dropping the OpenTelemetry chain is safe

posthog-js@1.387.0 dropped @opentelemetry/* as direct deps (1.364.1 declared five of them). The app never used the OTLP log exporter — there are no opentelemetry/otlp/protobufjs references anywhere in src/, and captureException uses PostHog's native $exception_list error-tracking path (independent of OTLP). Session recording and analytics are unaffected.

Why the dompurify bump is a pure security gain

The 3.4.x advisories all target IN_PLACE mode, addHook mutation, and Trusted-Types output. The app uses standard string-in/string-out DOMPurify.sanitize(html, config) with a static ALLOWED_TAGS list and none of those options — so the bump tightens edge-case security with no behavior change to email rendering.

Out of scope

npm audit (full, incl. dev) still reports 13 high in the dev-only toolchain (electron-buildernode-gypmake-fetch-happen/cacache/tar). These do not gate CI (which uses --omit=dev) and require breaking majors. Tracked separately.

Verification

  • npm ci reproduces the lockfile cleanly; dev deps intact
  • npm audit --omit=dev --audit-level=high0 vulnerabilities (exit 0)
  • npm run typecheck, npm run lint, npm run format:check
  • npm run build
  • ✅ Unit (1425) + integration (18) tests pass
  • ℹ️ Local e2e shows pre-existing keyboard-shortcut flakiness (window OS-focus on macOS) — confirmed identical on baseline main before this change, so unrelated to this diff; these pass in CI (headless Linux + xvfb).

Open in Devin Review

Pre-PR verdict: PASS

  • mode: full
  • sha: ad83529
  • generated: 2026-06-17T02:05:24.145Z
Phase Status Duration
eval:analyzer ✅ exit 0 17.4s
eval:features ✅ exit 0 37.0s
agentic-verify ✅ exit 0 133.0s
real-gmail:cached ✅ exit 0 11.5s

…fjs)

The Security Audit CI job (`npm audit --omit=dev --audit-level=high`) was
failing on every PR due to pre-existing high-severity advisories in the
production dependency tree (#176). Red on every PR desensitizes reviewers
and can mask a genuinely new vulnerability.

Scoped, in-range lockfile-only fix (no package.json range changes, no
breaking majors):

- hono 4.12.18 → 4.12.25 — HIGH (transitive via @modelcontextprotocol/sdk);
  fixes CORS/cookie/JWT/path-traversal advisories.
- posthog-js 1.364.1 → 1.387.0 — newer posthog-js no longer depends on the
  @opentelemetry/* OTLP log-exporter chain, which orphans and removes
  protobufjs (HIGH) plus the @opentelemetry/core moderates entirely. The app
  never used the OTLP exporter (no opentelemetry/protobufjs references in
  src/); captureException uses PostHog's native $exception_list path.
- dompurify 3.4.0 → 3.4.10, js-yaml 4.1.1 → 4.2.0, markdown-it 14.1.1 →
  14.2.0, nodemailer 8.0.5 → 8.0.11, qs 6.15.0 → 6.15.2 — prod moderates,
  all fixed in-range in the same pass.

After this, `npm audit --omit=dev` reports 0 vulnerabilities (all severities).
The dompurify advisories target IN_PLACE / addHook / Trusted-Types usage; the
app uses standard string-in/string-out sanitize with a static ALLOWED_TAGS
config, so the bump is a pure security gain with no behavior change.

Remaining 13 high are dev-only (electron-builder/node-gyp toolchain), do not
gate CI, and require breaking majors — tracked separately, out of scope here.

Verified: npm ci reproduces the lock, prod gate clean, typecheck + lint +
format + build + unit (1425) + integration (18) all pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown

No reviewable files after applying ignore patterns.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@ankitvgupta

Copy link
Copy Markdown
Owner Author

✅ Pre-PR verification — PASS

  • mode: full
  • sha: ad83529
  • generated: 2026-06-17T02:05:26.341Z
Phase Status Duration
eval:analyzer ✅ exit 0 17.4s
eval:features ✅ exit 0 37.0s
agentic-verify ✅ exit 0 133.0s
real-gmail:cached ✅ exit 0 11.5s
Agentic verification — summary

Agentic verification — verify-diff

  • SHA: ad83529
  • Verdict: pass
  • Anomalies: 0
  • Actions: 13 (ToolSearch×2, mcp__chrome-devtools__list_pages×1, mcp__chrome-devtools__select_page×1, mcp__chrome-devtools__take_snapshot×1, mcp__chrome-devtools__take_screenshot×3, mcp__chrome-devtools__click×1, mcp__chrome-devtools__evaluate_script×3, mcp__chrome-devtools__press_key×1)
  • Cost: $0.4455
  • Turns: 14

Summary

The PR is a package-lock.json-only dependency update. The most user-visible change was dompurify 3.4.0→3.4.10 (HTML email sanitization). I verified: (1) the app loads correctly, (2) an HTML email with inline image content renders properly via DOMPurify (colored placeholder blocks and formatted text all visible), (3) the sender sidebar populates correctly, (4) Escape-back navigation returns to the inbox with the correct focused row state, and (5) no console errors or error boundary triggers were observed. All existing core flows are unaffected by the lockfile update.

Agentic verification — literal trace
[2026-06-17T02:02:59.742Z] Auto-selected CDP port: 9223
[2026-06-17T02:02:59.742Z] mode=verify-diff sha=ad83529 action_budget=40 budget_usd=1.5
[2026-06-17T02:02:59.828Z] data mode: demo (diff is UI/scripts/tests only)
[2026-06-17T02:02:59.828Z] diff base=8fbea4442cc891937d0f05115a7945f41be8b9af 1 file changed, 64 insertions(+), 380 deletions(-)
[2026-06-17T02:02:59.828Z] changed files:
package-lock.json
[2026-06-17T02:02:59.828Z] Launching Electron in demo mode with --remote-debugging-port=9223...
[2026-06-17T02:03:24.997Z] CDP ready. Spawning agent...
[2026-06-17T02:03:31.208Z] session init — chrome-devtools tools: 29
[2026-06-17T02:03:42.598Z] tool#1: ToolSearch
[2026-06-17T02:03:42.598Z]   input: {"query":"select:mcp__chrome-devtools__list_pages,mcp__chrome-devtools__select_page,mcp__chrome-devtools__take_screenshot,mcp__chrome-devtools__take_snapshot,mcp__chrome-devtools__evaluate_script","max_results":5}
[2026-06-17T02:03:42.607Z] result#1:
  {"type":"tool_reference","tool_name":"mcp__chrome-devtools__list_pages"}
  {"type":"tool_reference","tool_name":"mcp__chrome-devtools__select_page"}
  {"type":"tool_reference","tool_name":"mcp__chrome-devtools__take_screenshot"}
  {"type":"tool_reference","tool_name":"mcp__chrome-devtools__take_snapshot"}
  {"type":"tool_reference","tool_name":"mcp__chrome-devtools__evaluate_script"}
[2026-06-17T02:03:47.567Z] tool#2: mcp__chrome-devtools__list_pages
[2026-06-17T02:03:47.567Z]   input: {}
[2026-06-17T02:03:47.667Z] result#2:
  ## Pages
  1: http://localhost:5173/ [selected]
[2026-06-17T02:03:50.738Z] tool#3: mcp__chrome-devtools__select_page
[2026-06-17T02:03:50.738Z]   input: {"pageId":1}
[2026-06-17T02:03:50.898Z] result#3:
  ## Pages
  1: http://localhost:5173/ [selected]
[2026-06-17T02:03:52.944Z] tool#4: mcp__chrome-devtools__take_snapshot
[2026-06-17T02:03:52.944Z]   input: {}
[2026-06-17T02:03:53.005Z] result#4:
  ## Latest page snapshot
  uid=1_0 RootWebArea "Exo" url="http://localhost:5173/"
    uid=1_1 heading "Exo" level="1"
    uid=1_2 button "me@example.com"
    uid=1_3 button "Search" description="Search (/)"
    uid=1_4 button "Compose" description="Compose (C)"
    uid=1_5 button "Settings" description="Settings"
    uid=1_6 button "Refresh" description="Refresh"
    uid=1_7 button "Inbox"
    uid=1_8 button "Sent"
    uid=1_9 button "Density: Default" description="Density: Default"
    uid=1_10 button "Priority12"
    uid=1_11 button "Other7"
    uid=1_12 button "Archive Ready 6"
    uid=1_13 button "Drafts 8"
    uid=1_14 button "Snoozed 2"
    uid=1_15 button "All19"
    uid=1_16 button "On-Call URGENT: Production issue affecting checkout flow Draft Joining the incident channel now. Quick context: The payment timeout issue might be related to the 15m"
    uid=1_17 button "Diana Hu Meeting Follow-up: Q4 Planning - Action Items Draft Hi Diana, Thanks for capturing these. Quick responses: 1. Budget proposal - I'll review and send c 30m"
    uid=1_18 button "Gustaf Alströmer Can you intro me to a few folks? Draft yup i'm on it 1h"
    uid=1_19 button "Dalton Caldwell friday? yo you free friday? was thinking we grab tacos... 2h"
    uid=1_20 button "Gustaf Alströmer Quick question about API rate limits Draft Hey Gustaf, Happy to help! Here are answers to your questions: 1. **Rate limit increase**: You can 3h"
    uid=1_21 button "Surbhi Sarna Landing Page Mockups - Inline Images Here are the design mockups for the new landing page... 3h"
    uid=1_22 button "Dr. Geoff Ralston Request for Strategic Advisory Input - FY2026 Planning I am writing to request your input on several strategic matters... 3h"
    uid=1_23 button "Kevin Hale Intro: Ankit <> Tim Brady (AI infrastructure) Draft Hi Tim, Great to e-meet you! Kevin has told me great things about what you're building at AIStack. 3h"
    uid=1_24 button "HR Team Interview Scheduling - Senior Engineer Candidate Draft Hi, I can do the Wednesday 10am-11am slot. Yes, please send over Jordan's resume - I'd like to rev 5h"
    uid=1_25 button "Nicolas Dessaigne Launch Readiness Review - v2.0 Release Thanks for the updates. We need your input on tooltip copy... 6h 6"
    uid=1_26 button "David Lieb Partnership technical requirements — need your input Draft Hi David, Great questions — here's a quick rundown: 1. **API throughput**: We're currently handlin 6h"
    uid=1_27 button "David Lieb Meeting to discuss partnership — finding a time Wednesday at 10am PT works perfectly! Could we do it over Zoom? 1d 4"
    uid=1_28 StaticText "Select an email to see details"
    uid=1_29 StaticText "Use j/k to navigate, Cmd+J for agent"
    uid=1_30 StaticText "j/k"
    uid=1_31 StaticText "navigate"
    uid=1_32 StaticText "Enter"
    uid=1_33 StaticText "open"
    uid=1_34 StaticText "r"
    uid=1_35 StaticText "reply"
    uid=1_36 StaticText "e"
    uid=1_37 StaticText "archive"
    uid=1_38 StaticText "u"
    uid=1_39 StaticText "unread"
    uid=1_40 StaticText "x"
    uid=1_41 StaticText "select"
    uid=1_42 StaticText "c"
    uid=1_43 StaticText "compose"
    uid=1_44 StaticText "/"
    uid=1_45 StaticText "search"
    uid=1_46 StaticText "b"
    uid=1_47 StaticText "sidebar"
    uid=1_48 StaticText "⌘K"
    uid=1_49 StaticText "commands"
  
[2026-06-17T02:04:06.941Z] text: The app loads correctly. The diff is a `package-lock.json`-only change with these key dependency updates: **dompurify** 3.4.0→3.4.10, **@posthog/core** 1.24.3→1.33.0, **js-yaml** 4.1.1→4.2.0, and removal of `@opentelemetry/*` and `@protobufjs/*` packages.

The most user-visible risk is `dompurify` (HTML email sanitization). I'll verify: email content renders, no console errors, and basic navigation works.
[2026-06-17T02:04:06.941Z] tool#5: mcp__chrome-devtools__take_screenshot
[2026-06-17T02:04:06.941Z]   input: {}
[2026-06-17T02:04:07.318Z] result#5:
  Took a screenshot of the current page's viewport.
  {"type":"image","source":{"type":"base64","media_type":"image/jpeg","data":"/9j/4AAQSkZJRgABAgAAAQABAAD/wAARCAU1B88DAREAAhEBAxEB/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9U6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAI5ZkhXLHHtQBWOpoDwjGnYVxP7UX/nm350WC4f2ov8Azzb86LBcP7UX/nm350WC4f2ov/PNvzosFw/tRf8Anm350WC4f2ov/PNvzosFw/tRf+ebfnRYLh/ai/8APNvzosFw/tRf+ebfnRYLh/ai/wDPNvzosFw/tRf+ebfnRYLh/ai/882/OiwXD+1F/wCebfnRYLh/ai/882/OiwXD+1F/55t+dFguH9qL/wA82/OiwXD+1F/55t+dFguH9qL/AM82/OiwXD+1F/55t+dFguH9qL/zzb86LBcP7UX/AJ5t+dFguH9qL/zzb86LBcP7UX/nm350WC4f2ov/ADzb86LBcP7UX/nm350WC4f2ov8Azzb86LBcP7UX/nm350WC4f2ov/PNvzosFw/tRf8Anm350WC4f2ov/PNvzosFw/tRf+ebfnRYLh/ai/8APNvzosFw/tRf+ebfnRYLh/ai/wDPNvzosFxy6mhPKstFguWkcSLlTkHuKQx1ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYfjHxrofgDQptY8QalBpenw9ZZj949lUDlmPoATXZhMHiMfVVDDQcpPt/WiMataFCPPUdkfOOtf8FBvCNneNHpvh7WdTgHHnkxQZ+isc4r9Do8BY2cb1asYvtq/wAjwp53RT92Lf3Iz/8Ah4hoX/Qm6v8A+BUH+Nb/AOoGI/6CI/dIj+3Kf8j+9B/w8Q0L/oTdX/8AAqD/ABo/1AxH/QRH7pB/blP+R/eg/wCHiGhf9Cbq/wD4FQf40f6gYj/oIj90g/tyn/I/vQf8PENC/wChN1f/AMCoP8aP9QMR/wBBEfukH9uU/wCR/eg/4eIaF/0Jur/+BUH+NH+oGI/6CI/dIP7cp/yP70H/AA8Q0L/oTdX/APAqD/Gj/UDEf9BEfukH9uU/5H96D/h4hoX/AEJur/8AgVB/jR/qBiP+giP3SD+3Kf8AI/vQf8PENC/6E3V//AqD/Gj/AFAxH/QRH7pB/blP+R/eg/4eIaF/0Jur/wDgVB/jR/qBiP8AoIj90g/tyn/I/vQf8PENC/6E3V//AAKg/wAaP9QMR/0ER+6Qf25T/kf3oP8Ah4hoX/Qm6v8A+BUH+NH+oGI/6CI/dIP7cp/yP70H/DxDQv8AoTdX/wDAqD/Gj/UDEf8AQRH7pB/blP8Akf3oP+HiGhf9Cbq//gVB/jR/qBiP+giP3SD+3Kf8j+9B/wAPENC/6E3V/wDwKg/xo/1AxH/QRH7pB/blP+R/eg/4eIaF/wBCbq//AIFQf40f6gYj/oIj90g/tyn/ACP70H/DxDQv+hN1f/wKg/xo/wBQMR/0ER+6Qf25T/kf3oP+HiGhf9Cbq/8A4FQf40f6gYj/AKCI/dIP7cp/yP70H/DxDQv+hN1f/wACoP8AGj/UDEf9BEfukH9uU/5H96JLf/god4deZRN4R1iKMn5nE8DY/DPNTLgDEpaV4/dIazyn1g/wPdfhV8dfB/xjtZH8Pajuu4Rum0+6XyrmIepQ9R7rkV8TmmSY3KJJYmGj2a1T+f6M9jDYyjil+7evbqeg14J2hQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAITgEntQBjTSmaQsfwHpVEkdMQUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAFmxmMcwX+FuKTGjVqSgoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo …[truncated, 449009 more chars]
[2026-06-17T02:04:12.015Z] text: Good — the inbox list renders cleanly. Now let me open an email with HTML content to verify DOMPurify sanitization works correctly.
[2026-06-17T02:04:12.032Z] tool#6: mcp__chrome-devtools__click
[2026-06-17T02:04:12.032Z]   input: {"uid":"1_21"}
[2026-06-17T02:04:15.230Z] result#6:
  Successfully clicked on the element
[2026-06-17T02:04:17.556Z] tool#7: mcp__chrome-devtools__take_screenshot
[2026-06-17T02:04:17.556Z]   input: {}
[2026-06-17T02:04:17.692Z] result#7:
  Took a screenshot of the current page's viewport.
  {"type":"image","source":{"type":"base64","media_type":"image/png","data":"iVBORw0KGgoAAAANSUhEUgAAB88AAAU1CAIAAAAS6RJTAAWmVUlEQVR4Ae3AA6AkWZbG8f937o3IzKdyS2Oubdu2bdu2bdu2bWmMnpZKr54yMyLu+Xa3anqmhztr1a/a5qqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676NwGA4Kqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676twKA4Kqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676twKA4Kqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676twKA4Kqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676twKA4Kqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676twKA4Kqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676twKA4Kqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676twKA4Kqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676twKA4Kqrrrrqqquuuuqqq6666qqrrrrqqquuuuqqq676twKAylVXXXXVVVddddVVV1111VVXXXXVVVdd9R/BJo1tm6v+z5CQFELiqqueLwCQba666qqrrrrqqquuuuqqq6666qqrrrrqqn8Hm5auRVz1f9fUXEISV131XABAtrnqqqteRKZl2k4bm6uuuurfTBJIiogIcdVVV1111VVXXXXVVVdd9b9ZmhBAS/7hacPt947nL+V6NFf979dXndyJm66pj31IP+sFpAlx1VUPBACVq6666kWQ6XGaWkvbtm1z1VVX/ftIEigUiq6WUgtXXXXVVVddddVVV1111VX/2xgEIc5daj/124d/9Her+y60+3bb/mGOzeKq/90MtWh7odPHy7Uny8s9Zv52r7N5w+kK2EhcddUVACDbXHXVVS/UMIzj1GzblsRVV131H8pGopSY9X2EuOqqq6666qqrrrrqqquu+l/CRgL4id86/M6f27v3wrRaez5TV1SKJK76P8CmpafGcp19p9PHyru+0fZ7v9k2YCNx1VUAAMg2V1111QuQ6WEYppZcddVV//kkzfpaa+Wqq6666qqrrrrqqquuuup/vDQhLu7nl//AxV/9k6OWzKoiSAPYXPV/hgARIs0wGniNl1588nueuO5UySSCq64CANnmqquuen4yvVoPLVNcddVV/3Vmfdd1lauuuuqqq6666qqrrrrqqv/B0oQ4f6l90jec/5O/X29vyGBz1f95EoKDpR/70P7LP+LUTdfUTCK46v85AAiuuuqq58ter4eWKa666qr/UuthnKbGVVddddVVV1111VVXXXXV/1Q2IYAv/t6Lf/x3q2Nbkcbmqv8PbNLsbMY/PHX4vO+8MIyOwOaq/+cAILjqqquen2GcWktx1VVX/TcYxtE2V1111VVXXXXVVVddddVV/yNJAD/y6we//mfLY1sxNXPV/zNT87Gt+OO/X3/XL+wDElf9PwcAwVVXXfU8WsthnBBXXXXVf4vWchhGrrrqqquuuuqqq6666qqr/qe6477pm37iUlfVkqv+f5qaFzN958/uPf7WATBX/b8GAMFVV131PMZx4qqrrvrvI2lqmZlcddVVV1111VVXXXXVVVf9D5MJ8KO/cbB/lCW46v8ziXHyD//qAVf9vwcAwVVXXfWcbE+tcdVVV/23ysypNa666qqrrrrqqquuuuqqq/4nsYlgNfi3/nyZ5qr/52xK6Hf+anlhrwnMVf9/AUBw1VVXPadpSq666qr/dlI221x11VVXXXXVVVddddVVV/3PkQb4s8etD5dZizBX/T8XwTj5j/5uDTi56v8tAAiuuuqq55SZXHXVVf/dBJkJ5qqrrrrqqquuuuqqq676f8y2zXOxzX8T28CTbx/2j7IE5qr/7yRWg5/wjAEw/z1scz/bXPXfAQCCq6666jmlk6uuuup/gLRtrrrqqquuuuqqq6666qr/nzLTtiSJ5yIJaC35L2cD3HWurQZHcNVVIabGHfdNgG3+a9kGJNkGAEm2+d/DdmbyPGxsZ2ZrrbVsrWWmbf6nAoDKVVdd9ZxsbCSuuuqq/162wSCuuuqqq6666qqrrrrqqv9nWmulFODsuQtPfurTl8vVX//tP6zXw7XXnLnxhmtf4sUefeMN15USrSW4lMJ/rcNlTg2Jq65CZPpgmfyXsy3J9uOe8OSf+rlf3t7avuXmG97mLd5Ikm1J/G8gSRIPYLu1VkqRJInn1DKxSyn8DwMAlauu+tebpokXhVRKEVddddVVV1111VVXXXXVVVddddVVL6rWWinlzrvu+cM/+Ysf/Ymfv3jpUt/1LRtQothGvNWbvcHrvuarPvIRDwVay1KCq6767yP+i7SW6RSSiAjg53/pN77mG7+z6zpgHMeLu5fe9z3e0XamjW2HVErhf6qLu5cuXNy95aYbuq4DWssI1VqBYRyf8MSn7B8chsL49KkT15w5ffzYDjBNLUIRwf8YAFC56qp/vVorV1111VVXXXXVVVddddVVV1111VX/0VpmKeW3f++Pvv17fuQZt91x8sRx0Gq1uu7aMwqdO3/x8PDo2M72j/7kz//yr/3OG7zOq7/2a77qiz3mEbYl8X9IBE7MVVc9W2aWEoXgfr/1u3/0Az/y04vFfGtzA7G3d/gzP/+rj3jog1/j1V6RB7ANkvifZhyn7/q+H/nt3/uTL/qcT3qxxzxyGMe+62z//C//xpOf8vTVav1Hf/qXFy7sRgnbN914/YNvufnmG697mZd+8Vd5xZcFMjMi+J8BACpXXfWvNIzjt33nDyyXy1LC5vmS1Fo7eeL427/tW+xsb9mWxFX/yWzznCTx/0lEAJnJVVddddVVV1111VVXXXXVVf8LtZalxHd+34/++E/9AtL29lbfd2/1Zm/wki/xmOM7O5L2Dg7GYfylX/vt3/uDP22t/fBP/Nzv/dGffcJHfdDLvcxL2JbE/wmZHK0861QK/34SQBrMFREANlf97xIRv/irv/VHf/KXN91w3Yu/2KNuvvGGn/2FX93b3z9arj7mw9//xhuu+4Iv+7q77r73J3/2l2666frz5y/+7d8//tZn3PHiL/aod3zbNwdsS+J/BtuSdi/t/c7v/8nFi5f+7h+e8GKPeWTfdX/513//PT/440968tMOj5a1lPl8fuLEMdvAhQu7589f/L0//JNf/+0/eMkXf/RbvdkbvsxLvZhtSfwPAACVq676V1qt1t/4rd994cLFrquGkCTZIJ4lpHEcH/Sgm9/w9V97Z3vLIK76T5SZJaJ2XYQk2diZmdPUbEcE/w/YHoYRqLVw1VVXXXXVVVddddVVV1111f82U2u1lF//rd//4R//2VrK1sbG67/Oq73pG7/eTTdcx3N6mZd68ae87a3f+l0/+KQnP+3Spf1v+Nbv/dLP/5TTp07alsT/ZhLrwTdfWz/yHY9/zy/u/d1Th8VMmfzbCBSs1ga6qgiATFaDJea9Mrnqf5GP/ZTPe9KTn757aW/Wd7/6m7+3vbV5cHjYWr7Cy77kq77yy89n/Zu90et+y3f+4NOfccdnff5XrtfD7qW9g8PDv/ybv//V3/jdr/+Kz5vPZ/wPY3s9jPP5bBhG4Md/+pd+4Ed+avfS3sZifvrUyb7vXuLFHnXD9ddNU6ulHB0tf+23fm9jY7FarX/n9//kSU95+sd/5Ae+7Eu/eNoh8d8NACpXXfWvZbpau67rugqM49haA/EADrXW2tRsc9V/psyUtLm5sVqudncvrYdhmqZSSt91/aw/vrODODxcRkgS/0dl5ubmxl/85d9+/pd87WzWf/WXfc7pkyeGcZTE/z/pNDYIhCQJcdVVV1111VVXXXX …[truncated, 489888 more chars]
[2026-06-17T02:04:23.716Z] text: HTML email content renders correctly with DOMPurify - formatted text, inline image placeholders, and sender sidebar all display properly. Now let me check for console errors and verify back navigation.
[2026-06-17T02:04:26.320Z] tool#8: mcp__chrome-devtools__evaluate_script
[2026-06-17T02:04:26.320Z]   input: {"function":"() => {\n  return {\n    consoleErrors: window.__exoErrors__ || [],\n    selectedRows: document.querySelectorAll(\"[data-thread-id][data-selected='true']\").length,\n    senderName: document.querySelector(\"[data-testid='sidebar-sender-name']\")?.textContent ?? null,\n    domPurifyPresent: typeof window.DOMPurify !== 'undefined' || document.querySelector('[data-dompurify]') !== null,\n    emailBodyVisible: document.querySelector('.email-body, [class*=\"emailBody\"], [class*=\"email-content\"]')?.textContent?.substring(0, 50) ?? null\n  };\n}"}
[2026-06-17T02:04:26.533Z] result#8:
  Script ran on page and returned:
  ```json
  {"consoleErrors":[],"selectedRows":0,"senderName":"Surbhi Sarna","domPurifyPresent":false,"emailBodyVisible":null}

[2026-06-17T02:04:30.292Z] text: No console errors. Sender sidebar showing "Surbhi Sarna" correctly. Now let me press Escape/Back and verify the detail view closes and we return to the inbox properly.
[2026-06-17T02:04:32.526Z] tool#9: mcp__chrome-devtools__evaluate_script
[2026-06-17T02:04:32.527Z] input: {"function":"() => {\n // Check for any JS errors in the error boundary or window.onerror\n const errors = [];\n // Check if there are any visible error messages in the DOM\n const errorElements = document.querySelectorAll('[class*="error"], [class*="Error"]');\n errorElements.forEach(el => {\n if (el.textContent && el.textContent.trim().length > 0 && el.offsetParent !== null) {\n errors.push(el.textContent.trim().substring(0, 100));\n }\n });\n return { visibleErrors: errors.slice(0, 5) };\n}"}
[2026-06-17T02:04:32.739Z] result#9:
Script ran on page and returned:

{"visibleErrors":[]}

[2026-06-17T02:04:35.454Z] text: No visible errors. Now I'll click Back to return to the inbox and verify clean state.
[2026-06-17T02:04:35.927Z] tool#10: ToolSearch
[2026-06-17T02:04:35.927Z] input: {"query":"select:mcp__chrome-devtools__click,mcp__chrome-devtools__press_key","max_results":2}
[2026-06-17T02:04:35.931Z] result#10:
{"type":"tool_reference","tool_name":"mcp__chrome-devtools__click"}
{"type":"tool_reference","tool_name":"mcp__chrome-devtools__press_key"}
[2026-06-17T02:04:38.100Z] tool#11: mcp__chrome-devtools__press_key
[2026-06-17T02:04:38.100Z] input: {"key":"Escape"}
[2026-06-17T02:04:38.313Z] result#11:
Successfully pressed key: Escape
[2026-06-17T02:04:40.488Z] tool#12: mcp__chrome-devtools__take_screenshot
[2026-06-17T02:04:40.488Z] input: {}
[2026-06-17T02:04:40.723Z] result#12:
Took a screenshot of the current page's viewport.
{"type":"image","source":{"type":"base64","media_type":"image/jpeg","data":"/9j/4AAQSkZJRgABAgAAAQABAAD/wAARCAU1B88DAREAAhEBAxEB/9sAQwADAgIDAgIDAwMDBAMDBAUIBQUEBAUKBwcGCAwKDAwLCgsLDQ4SEA0OEQ4LCxAWEBETFBUVFQwPFxgWFBgSFBUU/9sAQwEDBAQFBAUJBQUJFA0LDRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9U6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAI5ZkhXLHHtQBWOpoDwjGnYVxP7UX/nm350WC4f2ov8Azzb86LBcP7UX/nm350WC4f2ov/PNvzosFw/tRf8Anm350WC4f2ov/PNvzosFw/tRf+ebfnRYLh/ai/8APNvzosFw/tRf+ebfnRYLh/ai/wDPNvzosFw/tRf+ebfnRYLh/ai/882/OiwXD+1F/wCebfnRYLh/ai/882/OiwXD+1F/55t+dFguH9qL/wA82/OiwXD+1F/55t+dFguH9qL/AM82/OiwXD+1F/55t+dFguH9qL/zzb86LBcP7UX/AJ5t+dFguH9qL/zzb86LBcP7UX/nm350WC4f2ov/ADzb86LBcP7UX/nm350WC4f2ov8Azzb86LBcP7UX/nm350WC4f2ov/PNvzosFw/tRf8Anm350WC4f2ov/PNvzosFw/tRf+ebfnRYLh/ai/8APNvzosFw/tRf+ebfnRYLh/ai/wDPNvzosFxy6mhPKstFguWkcSLlTkHuKQx1ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYfjHxrofgDQptY8QalBpenw9ZZj949lUDlmPoATXZhMHiMfVVDDQcpPt/WiMataFCPPUdkfOOtf8FBvCNneNHpvh7WdTgHHnkxQZ+isc4r9Do8BY2cb1asYvtq/wAjwp53RT92Lf3Iz/8Ah4hoX/Qm6v8A+BUH+Nb/AOoGI/6CI/dIj+3Kf8j+9B/w8Q0L/oTdX/8AAqD/ABo/1AxH/QRH7pB/blP+R/eg/wCHiGhf9Cbq/wD4FQf40f6gYj/oIj90g/tyn/I/vQf8PENC/wChN1f/AMCoP8aP9QMR/wBBEfukH9uU/wCR/eg/4eIaF/0Jur/+BUH+NH+oGI/6CI/dIP7cp/yP70H/AA8Q0L/oTdX/APAqD/Gj/UDEf9BEfukH9uU/5H96D/h4hoX/AEJur/8AgVB/jR/qBiP+giP3SD+3Kf8AI/vQf8PENC/6E3V//AqD/Gj/AFAxH/QRH7pB/blP+R/eg/4eIaF/0Jur/wDgVB/jR/qBiP8AoIj90g/tyn/I/vQf8PENC/6E3V//AAKg/wAaP9QMR/0ER+6Qf25T/kf3oP8Ah4hoX/Qm6v8A+BUH+NH+oGI/6CI/dIP7cp/yP70H/DxDQv8AoTdX/wDAqD/Gj/UDEf8AQRH7pB/blP8Akf3oP+HiGhf9Cbq//gVB/jR/qBiP+giP3SD+3Kf8j+9B/wAPENC/6E3V/wDwKg/xo/1AxH/QRH7pB/blP+R/eg/4eIaF/wBCbq//AIFQf40f6gYj/oIj90g/tyn/ACP70H/DxDQv+hN1f/wKg/xo/wBQMR/0ER+6Qf25T/kf3oP+HiGhf9Cbq/8A4FQf40f6gYj/AKCI/dIP7cp/yP70H/DxDQv+hN1f/wACoP8AGj/UDEf9BEfukH9uU/5H96JLf/god4deZRN4R1iKMn5nE8DY/DPNTLgDEpaV4/dIazyn1g/wPdfhV8dfB/xjtZH8Pajuu4Rum0+6XyrmIepQ9R7rkV8TmmSY3KJJYmGj2a1T+f6M9jDYyjil+7evbqeg14J2hQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAITgEntQBjTSmaQsfwHpVEkdMQUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAFmxmMcwX+FuKTGjVqSgoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo …[truncated, 509685 more chars]
[2026-06-17T02:04:50.357Z] text: Back navigation works — inbox list restored. The Surbhi Sarna row shows highlighted (last-viewed indicator) and sidebar retains the sender panel. Let me verify the selection state via DOM query to be thorough.
[2026-06-17T02:04:51.990Z] tool#13: mcp__chrome-devtools__evaluate_script
[2026-06-17T02:04:51.990Z] input: {"function":"() => {\n return {\n selectedRows: document.querySelectorAll("[data-thread-id][data-selected='true']").length,\n senderName: document.querySelector("[data-testid='sidebar-sender-name']")?.textContent ?? null,\n emptySidebar: document.body.innerText.includes("Select an email to see details"),\n pageTitle: document.title,\n bodyContainsError: document.body.innerText.toLowerCase().includes('error') && \n document.body.innerText.toLowerCase().includes('boundary')\n };\n}"}
[2026-06-17T02:04:52.201Z] result#13:
Script ran on page and returned:

{"selectedRows":1,"senderName":"Surbhi Sarna","emptySidebar":false,"pageTitle":"Exo","bodyContainsError":false}

[2026-06-17T02:05:12.287Z] text: Everything looks clean. The single selectedRows: 1 is expected — the Surbhi Sarna row is highlighted as the last-viewed item for keyboard navigation focus, which is normal app behavior (not a regression).

Summary of what I verified:

  • This PR is package-lock.json-only — it updates dompurify 3.4.0→3.4.10, @posthog/core 1.24.3→1.33.0, js-yaml 4.1.1→4.2.0, hono and @posthog/types, and removes @opentelemetry/* + @protobufjs/* packages
  • DOMPurify (primary user-visible risk): opened an HTML email with inline image placeholders — content rendered correctly including formatted sections and image blocks
  • Navigation: opened email, pressed Escape to return to list — worked correctly, inbox restored, no stale UI or error states
  • No JS console errors, no visible error UI, no error boundary triggers
  • App title, email list, sender sidebar, and priority tabs all functional

{"verdict":"pass","summary":"The PR is a package-lock.json-only dependency update. The most user-visible change was dompurify 3.4.0→3.4.10 (HTML email sanitization). I verified: (1) the app loads correctly, (2) an HTML email with inline image content renders properly via DOMPurify (colored placeholder blocks and formatted text all visible), (3) the sender sidebar populates correctly, (4) Escape-back navigation returns to the inbox with the correct focused row state, and (5) no console errors or error boundary triggers were observed. All existing core flows are unaffected by the lockfile update.","anomalies":[],"actions_taken":11}
[2026-06-17T02:05:12.340Z] result: subtype=success cost=0.44546754999999993 turns=14


</details>


<sub>This comment is upserted by `npm run pre-pr`. The CI gate reads the marker block in the PR description, not this comment.</sub>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Security Audit CI fails: high-severity vulns in production deps (hono, protobufjs)

1 participant