Skip to content

chore(deps): update actions/cache digest to 55cc834#1108

Merged
Wikid82 merged 1 commit into
developmentfrom
renovate/github-actions-non-major
Jun 27, 2026
Merged

chore(deps): update actions/cache digest to 55cc834#1108
Wikid82 merged 1 commit into
developmentfrom
renovate/github-actions-non-major

Conversation

@renovate

@renovate renovate Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Type Update Change
actions/cache (changelog) action digest 2c8a9bd55cc834

Configuration

📅 Schedule: (in timezone America/New_York)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@github-advanced-security

Copy link
Copy Markdown
Contributor

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Supply Chain Verification Results

PASSED

📦 SBOM Summary

  • Components: 1485

🔍 Vulnerability Scan

Severity Count
🔴 Critical 0
🟠 High 0
🟡 Medium 4
🟢 Low 2
Total 6

📎 Artifacts

  • SBOM (CycloneDX JSON) and Grype results available in workflow artifacts

Generated by Supply Chain Verification workflow • View Details

@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Wikid82 Wikid82 merged commit e010a91 into development Jun 27, 2026
40 checks passed
@renovate renovate Bot deleted the renovate/github-actions-non-major branch June 27, 2026 02:11
Wikid82 added a commit that referenced this pull request Jun 29, 2026
* chore(deps): update github-actions-non-major

* chore(deps): update go-non-major

* chore(deps): update npm-non-major

* fix: regenerate lockfile to restore missing eslint and vite package entries

Renovate's automated update regenerated package-lock.json incorrectly,
omitting top-level node_modules entries for eslint and vite. This caused
npm ci to fail in CI during dependency installation. Regenerating with
Node v22.22.1 and npm v11.16.0 restores the correct entries.

* fix(security): restore stale Grype code scanning pipeline

The supply-chain Grype scan last ran on Feb 4, 2026 due to a cascade of
compounding failures. This commit resolves all root causes:

- Twelve .trivyignore CVE suppressions expired between Apr 30 and May 25,
  causing the Trivy PR gate to block all PR merges and starve the pipeline
  of push events. All entries extended 60–90 days with appropriate review
  comments; no entry exceeds Sep 1, 2026.

- Ten .grype.yaml suppressions also expired in May, meaning Grype scans
  that did run would immediately fail on HIGH findings and produce no fresh
  SARIF. All entries extended with matching dates.

- The supply-chain-pr.yml job condition had a dead workflow_run branch and
  was missing the push and schedule event names, silently skipping the
  verify-supply-chain job on every push to main. Added push and schedule to
  the condition.

- Added a weekly schedule trigger (Mondays at 02:00 UTC) so scans run
  regardless of PR activity. Added development to push branches to match
  docker-build.yml scope.

- Removed continue-on-error: true from the SARIF upload step so upload
  failures surface as visible workflow failures rather than silent no-ops.

- Simplified concurrency.group to remove dead workflow_run expressions.

Refs: GitHub Code Scanning "last scanned Feb 4, 2026" alert

* fix(deps): update Renovate configuration to correctly map gopkg.in/yaml.v3

* chore(deps): update go-non-major

* fix(deps): update Caddy version to 2.11.4 in Dockerfile

* fix(deps): update prometheus/common to v0.68.1

* fix(deps): update @tanstack/react-query to v5.101.0 and axios to v1.17.0

* fix(deps): update Go version to 1.26.4 in settings, Dockerfile, and module files

* fix(deps): update Syft version to v1.45.0 in multiple workflows and scripts

* fix(theme): prevent flash of unstyled content on page load

Add anti-FOUC inline script to index.html that applies the stored theme
class synchronously before React mounts. Switch ThemeContext to useLayoutEffect
for synchronous class application, add explicit light-mode CSS overrides, update
CSP to allowlist the inline script hash, and add a Playwright regression suite.

* fix(dep): update grype version to 0.113.0

* fix(go): align all workflow and VS Code go.goroot references to 1.26.4

Update GO_VERSION from 1.26.3 to 1.26.4 in all 9 CI workflow files and
fix go.goroot in .vscode/settings.json to point to /usr/local/go where
1.26.4 is installed, replacing the missing sdk/go1.26.4 path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(deps): update go-non-major to v1.75.0

* fix(ci): resolve Go toolchain mismatch in CodeQL and all CI workflows

Switch setup-go from go-version env var to go-version-file: backend/go.mod
so the action reads the required version directly from go.mod instead of
relying on a cached toolchain version that may lag behind. Change
GOTOOLCHAIN from auto to local across all workflows so Go uses exactly the
version installed by setup-go without attempting auto-downloads that can
silently fall back to an older release.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(sec): patch CVE-2026-40898 in buger/jsonparser via crowdsec-builder

Upgrades github.com/buger/jsonparser to v1.1.2 in the CrowdSec
dependency patch block to fix a panic in Delete() caused by a
negative slice index on malformed JSON input. Affects both the
crowdsec and cscli binaries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(deps): update go-non-major

* chore(deps): update i18next version to 26.3.1

* chore(deps): update github-actions-non-major

* chore(deps): update go-non-major

* fix(deps): update npm-non-major to ^7.17.0

* fix(sec): patch CVE-2026-40898 in buger/jsonparser via caddy-builder

Adds go get github.com/buger/jsonparser@v1.2.0 to the xcaddy build
stage. The Caddy binary embeds buger/jsonparser transitively through
caddy-crowdsec-bouncer -> crowdsec, which Trivy flags as a blocker.
The crowdsec-builder stage already had this pin; this closes the gap
in the caddy-builder stage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(sec): patch CVE-2026-40898 (quic-go QPACK) in crowdsec-builder

CVE-2026-40898 / GHSA-vvgj-x9jq-8cj9 is a quic-go HTTP/3 QPACK Trailer
Expansion Memory Exhaustion, fixed in github.com/quic-go/quic-go@v0.59.1.
CrowdSec v1.7.8 embeds quic-go v0.57.0; this is what Trivy flags as 2
blockers (crowdsec + cscli binaries). Caddy already resolves v0.59.1
through its own module graph and is unaffected.

Also corrects the caddy-builder comment for buger/jsonparser, which was
incorrectly attributed to CVE-2026-40898 in the prior commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(sec): suppress GO-2024-2565, GO-2024-2557, GO-2026-4518 in grype/trivy

Three new findings block CI on the development branch:

- GO-2024-2565 / CVE-2024-21495 (CRITICAL): Insufficient randomness in
  caddy-security. FALSE POSITIVE — Go vulndb has no fixed version recorded,
  but per Snyk/NVD the fix shipped in v1.0.42; we run v1.1.62. Suppressed
  with documented rationale pending Go vulndb update.

- GO-2024-2557 / CVE-2024-21492 (HIGH): Insufficient session expiration in
  caddy-security. No upstream fix; stateless JWT architecture means no
  server-side revocation. JWT TTL bounds exploitation window. Risk accepted.

- GO-2026-4518 (HIGH): Go vulndb alias for the pgproto3/v2 DataRow negative
  field length panic already suppressed under GHSA-jqcq-xjh3-6g23 /
  CVE-2026-4427. Same EOL-module rationale applies.

All entries include expiry dates (2026-09-05 for caddy-security, 2026-09-01
for pgproto3) and removal criteria. .trivyignore updated for the two CVE IDs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(dep) update syft to v 1.45.1 in multiple workflows

* fix(dep): update knip to v 6.16.0

* fix(dep): update bytedance/sonic to v1.15.2 and mattn/go-sqlite3 to v1.14.45

* chore: add Claude Code configuration from .github copilot files

Convert the project's GitHub Copilot configuration into native Claude Code
equivalents so the same team conventions, agent roles, and slash commands
work out-of-the-box in Claude Code sessions.

- CLAUDE.md — project-wide instructions adapted from copilot-instructions.md;
  covers architecture rules, backend/frontend workflows, DoD checklist, and
  a quick-reference skills table
- .claude/agents/ — nine specialized subagents (management, planning,
  supervisor, backend-dev, frontend-dev, qa-security, devops, docs-writer,
  playwright-dev) translated from .github/agents/*.agent.md, with VS Code-
  specific frontmatter removed and references updated to CLAUDE.md
- .claude/commands/ — five slash commands translated from .github/prompts/:
  /create-implementation-plan, /debug-web-console-errors,
  /supply-chain-remediation, /playwright-generate-test, /fix-patch-coverage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(frontend): remove deprecated Firefox CSS and add modern browserslist targets (#1060)

Remove -moz-osx-font-smoothing (Firefox never supported it; -webkit-font-smoothing
already handles Chrome/Safari). Add .browserslistrc targeting modern browsers so
autoprefixer stops emitting legacy -moz- vendor prefixes eliminated from Firefox ESR+.

Co-authored-by: GitHub Actions <actions@github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: update ignore files

* fix(dep) update npm deps to lates versions

* chore(deps): update dependency anchore/syft to v1.45.1 (#1061)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency anchore/grype to v0.114.0 (#1062)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(dep): update codecov action

* chore(docker): update GeoLite2-Country.mmdb checksum (#1064)

Automated checksum update for GeoLite2-Country.mmdb database.

Old: c77ac1d7e64b3fcd1447045615fc3aefb3ed886e176608c568b01f29f955e21a
New: abce3a42f4f6bfb2c90cded582341da6764f5e152782ce6c832bc8fa1d873778

Auto-generated by: .github/workflows/update-geolite2.yml

Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>

* fix(assets): serve banner.webp and use picture element for optimized image delivery (#1063)

* fix(assets): serve banner.webp and use picture element for optimized image delivery

Register /banner.webp, /banner.svg, /logo.webp, and /logo.svg as static
routes so browsers receive WebP variants with correct MIME types instead
of falling through to index.html. Replace the bare <img src="/banner.png">
in the sidebar with a <picture> element that serves the 74%-smaller WebP
to capable browsers and falls back to PNG, eliminating NS_BINDING_ABORTED
caused by the 1.2 MB PNG stalling under load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: remove tracked worktree gitlink and ignore .claude/worktrees/

The .claude/worktrees/enumerated-snacking-parnas path was committed as a
gitlink (unregistered submodule), causing `git submodule foreach` to exit
with code 128 and failing Codecov upload steps in CI. Remove it from the
index and add .claude/worktrees/ to .gitignore so future worktrees are
never inadvertently staged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: GitHub Actions <actions@github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(deps): bump quic-go, maxminddb, and sqlite dependencies

* chore(deps): bump knip from 6.16.0 to 6.16.1

* docs: add no-worktrees instruction to CLAUDE.md

* chore(deps): bump react-hook-form and eslint-plugin-unicorn

* chore: ignore gorilla/websocket in renovate updates

* fix(deps): add Renovate sourceUrl overrides for gin packages (#1065)

* chore(deps): bump quic-go, maxminddb, and sqlite dependencies

* fix(deps): add sourceUrl overrides for gin packages in Renovate config

Renovate fails to resolve github.com/gin-gonic/gin and its sibling
packages gin-contrib/gzip and gin-contrib/sse with a "no-result" error.
Adds three sourceUrl packageRules entries following the established
pattern already present for google/uuid, gorm.io/gorm, and other Go
packages in this repo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: GitHub Actions <actions@github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: clean node_modules before npm install in update script

* chore(frontend): bump typescript-eslint to 8.61.0 and update deps

* chore: bump dev dependencies (obug, semver, tinyexec)

* chore(deps): bump golang.org/x/sys from v0.45.0 to v0.46.0

* chore(deps): bump golang.org/x and modernc.org dependencies

* fix(ci): pass pr_number when dispatching security-pr.yml from weekly promotion

The trigger-required-checks job in weekly-nightly-promotion.yml dispatched
security-pr.yml without providing the required pr_number input, causing
HttpError: Required input 'pr_number' not provided. The fix resolves the
PR number from the create-promotion-pr job output and passes it as an
input when dispatching the security workflow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): extend no-cache-filters to caddy-builder and crowdsec-builder in e2e workflow

Prevents stale GHA BuildKit layer cache from serving outdated caddy-builder
and crowdsec-builder stage outputs in e2e-tests-split.yml, mirroring the
same fix already applied to nightly-build.yml for CVE-2026-45135.

Also corrects a stale fallback version comment in Dockerfile (v2.11.3 → v2.11.4)
and updates SECURITY.md to mark CVE-2026-45135 as fully remediated across all
affected build workflows.

* chore: bump prettier from 3.8.3 to 3.8.4

* chore(deps): bump eslint-plugin-unicorn to 65.0.1

* fix(dockerfile): gate Delve install on BUILD_DEBUG, pin x/sys for GO-2026-5024

Production builds now install a harmless stub instead of Delve to avoid
shipping golang.org/x/sys < v0.27.0 (GO-2026-5024). Debug builds pin
golang.org/x/sys to v0.46.0 via a temporary module before installing dlv.

* fix(entrypoint): gracefully handle production dlv stub when CHARON_DEBUG=1

The GO-2026-5024 fix replaced the Delve binary with a shell stub in
production images. When CI integration tests run with CHARON_DEBUG=1,
the entrypoint tried to launch `dlv exec /app/charon`, the stub exited
immediately with code 1, APP_PID captured the dead stub PID, and the
wait loop triggered container shutdown before Charon ever started.

Guard the Delve path with `dlv version` — real Delve exits 0, the stub
exits 1 — and fall back to direct execution when the stub is detected.

* chore(deps): update go-non-major (#1058)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>

* chore(deps): update github-actions-non-major to v46.1.15 (#1067)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>

* fix(deps): update go-non-major to v0.7.2 (#1068)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update alpine docker tag to v3.24.0 (#1069)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): bump go-pkcs12 from v0.7.1 to v0.7.2

* chore: bump semver from 7.8.3 to 7.8.4

* chore(deps): bump frontend dev dependencies to latest patch versions

* chore: replace eslint-plugin-react-compiler with react-hooks built-in

* fix(frontend): unregister auth error handler on AuthProvider unmount (#1070)

Issue #579 reported that page reload did not redirect to /login when the
session expired. Root-cause tracing showed the reload guard already works
on development (all 16 auth E2E tests pass), but the trace surfaced a real
hazard: the axios 401 interceptor kept a stale handler closure after
AuthProvider unmounted. setAuthErrorHandler now accepts null and the
provider unregisters its handler on unmount.

Adds regression tests for RequireAuth, AuthContext mount/unmount handler
lifecycle, and the client interceptor null-handler path.

Closes #579

Co-authored-by: GitHub Actions <actions@github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* chore: bump golang.org/x/net from v0.55.0 to v0.56.0

* chore: bump @napi-rs/wasm-runtime from 1.1.4 to 1.1.5

* chore: bump frontend dev dependencies to latest versions

* chore: add Docker Scout CLI install script

* fix(docker): move frontend builder to node alpine3.24 base to clear critical/high base-image CVEs

The pinned node:24.16.0-alpine (alpine 3.23) base was flagged with 1
critical and 8 high vulnerabilities. Repin to the freshly published
alpine 3.24 variant, which also aligns the builder with the alpine 3.24
runtime base. Remaining openssl advisories (CVE-2026-45447) are patched
in-stage by the existing apk upgrade step; the rebuilt stage scans clean
for critical/high findings.

* chore: bump @types/node from 25.9.2 to 25.9.3

* chore: remove lint step from npm_update script

* chore: enhance go_update.sh with vuln checks and test runs

- Auto-install govulncheck if missing
- Update go/toolchain directives before deps
- Include test dependencies with -t flag
- Run tests and govulncheck after each module update

* fix(go_update): simplify PATH export and remove redundant list cmd

* chore(renovate): group Dockerfile ARG updates separately from Go/NPM

- Replace Go github-tags Dockerfile fallback rule with a generic
  custom.regex + Dockerfile filename matcher
- New group: dockerfile-non-major with "dockerfile" label
- Preserves npm-non-major grouping rule unchanged

* chore(deps): update go-non-major to v0.56.0 (#1071)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore: update acorn from 8.16.0 to 8.17.0

* chore: bump frontend deps (acorn, caniuse-lite, enhanced-resolve)

* chore: bump felixge/httpsnoop from v1.0.4 to v1.1.0

* chore: update frontend lock file dependencies

* fix(security): prepare for npm v12 breaking changes (#1072)

* chore(ci): bump e2e workflow Node to 24.12.0 and track NODE_VERSION via Renovate

Node 20 is EOL and will be unsupported by npm 12. Adds a Renovate custom
manager so all workflow NODE_VERSION pins receive update PRs.

* fix(security): disable dependency install scripts for all npm installs

Adopts npm v12's secure default today: every npm ci/install call site
(CI workflows, Dockerfile, Makefile, scripts, package.json pre-hooks)
now passes --ignore-scripts, and unrs-resolver's postinstall is
explicitly denied via allowScripts (it ships prebuilt binaries; the
script is only a fallback build). Verified: clean installs, frontend
build, type-check, and full unit suite all pass with scripts disabled.

---------

Co-authored-by: GitHub Actions <actions@github.com>

* chore: bump eslint-plugin-security to 4.0.1

* chore: bump npm to 11.17.0

* chore(frontend): bump lucide-react, tailwindcss, and eslint deps

* chore: bump obug from 2.1.2 to 2.1.3

* chore(deps): bump modernc.org/libc from v1.73.0 to v1.73.1

* chore: fix renovate datasource config for expr-lang/expr

* chore(deps): bump react-hook-form from 7.78.0 to 7.79.0

* chore(deps): update npm-non-major to ^10.5.0 (#1073)

* chore(deps): update npm-non-major to ^10.5.0

* fix: regenerate frontend lock file to restore missing eslint@10.5.0 entries

Renovate's automated update removed top-level node_modules entries for
eslint@10.5.0 (and transitive deps eslint-visitor-keys, ignore) from
frontend/package-lock.json, causing all CI jobs to fail at npm ci.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: GitHub Actions <actions@github.com>

* chore: bump regjsparser from 0.13.1 to 0.13.2

* chore: update go.work.sum with golang.org/x/term v0.44.0

* chore(deps): bump modernc.org/libc from v1.73.1 to v1.73.3

* chore: bump @csstools/css-color-parser to 4.1.4

* chore(deps): update eslint-plugin-unicorn to v66 and react-refresh to v0.5.3

* chore(docker): update GeoLite2-Country.mmdb checksum (#1074)

Automated checksum update for GeoLite2-Country.mmdb database.

Old: abce3a42f4f6bfb2c90cded582341da6764f5e152782ce6c832bc8fa1d873778
New: 11b88595d026953920668d91f6d531057b397f05170237fc98a13a8b051ab861

Auto-generated by: .github/workflows/update-geolite2.yml

Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>

* chore: bump tldts, playwright, and vitest deps

* chore: bump mongo-driver to v2.6.1 and modernc/libc to v1.73.4

* chore(deps): update node.js to 21f403a (#1077)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update alpine docker tag to v3.24.1 (#1078)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dockerfile-non-major (#1079)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update github-actions-non-major (#1080)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update node.js to v24.16.0 (#1081)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update npm-non-major (#1082)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency eslint-plugin-unicorn to v67 (#1083)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update npm-non-major to ^7.18.0 (#1084)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* feat: enhanced dashboard with statistics (#25) (#1075)

* feat(models): add RequestLog model and AutoMigrate registration

Adds RequestLog struct to record proxied HTTP requests for the enhanced
dashboard statistics feature (issue #25). Includes BeforeCreate hook for
UUID generation, compound (host_id, timestamp) indexes, and GDPR-safe
pseudonymised client IP hashing. Registers model in AutoMigrate.

* feat(services): add StatsIngester for log fan-out and batch DB writes

- Add stats_types.go with StatsPushData, HostStat, StatusStat,
  StatsPushMessage, and BroadcastHub interface (avoids import cycles)
- Add StatsIngester: channel buffer=1000, batch flush at 100 entries
  or 500ms interval via CreateInBatches; atomic dropped-count tracking
- Hash client IPs with SHA-256 (first 16 bytes, hex) for GDPR safety
- Add LogWatcher.RegisterIngester() + fan-out in broadcast()
- TDD: 6 tests covering count-flush, timer-flush, back-pressure,
  graceful Stop drain, IP hashing determinism, and fan-out wiring

* feat(services): add StatsService with aggregation queries and TTL cache

Adds StatsService providing GetSummary (30s TTL cache), GetTopHosts,
GetStatusDistribution, GetTrafficVolume, and GetCertExpiry with input
validation allowlists. Extends stats_types.go with StatsSummary,
TrafficBucket, and CertExpiry types.

* feat(frontend/api): add stats API client and TypeScript type definitions

Add typed API functions and interfaces for all 8 stats endpoints (summary,
top-hosts, status-distribution, traffic-volume, cert-expiry, requests, health,
and WebSocket hub) with full Vitest test coverage (33 tests).

* feat(frontend/hooks): add useStats and useStatsWebSocket hooks

Add six TanStack Query hooks (useStatsSummary, useTopHosts,
useStatusDistribution, useTrafficVolume, useCertExpiry, useStatsHealth)
with stable query keys and appropriate polling intervals. Add
useStatsWebSocket hook that tracks live summary updates via the stats
WebSocket and disables REST polling when connected. Full Vitest coverage
for all hooks (22 tests).

Also remove unicorn/no-array-for-each ESLint rule removed in unicorn v66.

* feat(frontend/components): add stats chart and widget components

Add 8 pure presentational components under frontend/src/components/stats/:
- RequestCountWidget: 3-stat card for 24h/7d/30d request counts
- TopHostsChart: horizontal bar chart (recharts BarChart)
- StatusDistributionChart: donut chart with accessible HTML summary list
- TrafficVolumeChart: line chart with KB/MB Y-axis formatting
- CertExpiryList: accessible table with red/amber/green day-based color coding
- ServiceHealthWidget: WebSocket live/offline indicator + dropped-event warning
- PeriodSelector: controlled radio button group for 24h/7d/30d
- BucketSelector: controlled radio button group for 1h/6h/1d

All components are pure (no data fetching), strictly typed with no `any` types,
and keyboard accessible. Includes 58 Vitest unit tests covering loading states,
data rendering, color coding, and interaction callbacks.

* feat(frontend/dashboard): integrate stats sections into Dashboard page

Add a responsive Statistics section to the Dashboard page below the
existing content. Uses useStatsWebSocket for live updates, useState for
period/bucket controls, and the six stats hooks + eight stats components
(RequestCountWidget, ServiceHealthWidget, CertExpiryList,
TrafficVolumeChart, TopHostsChart, StatusDistributionChart,
PeriodSelector, BucketSelector). Layout is mobile-first with single
column on small screens, 2-col on sm/md, 3-col top row on lg.
Adds dashboard.statistics and dashboard.trafficVolume i18n keys to all
five locale files. Expands Dashboard tests from 3 to 12 cases.

* test(e2e): add Playwright tests for enhanced dashboard statistics

- tests/stats.spec.ts: 12 E2E tests covering all 9 required scenarios
  (stats heading, period selector, bucket selector, request count widget,
  service health widget, cert expiry section, traffic/top-hosts/status
  distribution chart containers) plus accessibility radio-count assertion
- backend/internal/api/handlers/stats_api_integration_test.go: adds
  TestStatsAPI_CertExpiry_366Days_Returns400 to cover the upper-bound
  validation (within_days > 365 returns HTTP 400); simplifies function
  signature to remove unused return value
- backend/internal/services/stats_ingester_test.go: adds
  TestStatsIngester_RegisterHub and TestStatsIngester_ToRequestLog_InvalidTimestamp
  to cover the RegisterHub wiring path and the timestamp parse-error fallback

All 12 E2E tests pass against the running E2E container at :8080.
Backend unit tests pass (88.4% coverage, above 87% minimum).
Frontend tests pass (87.86% statement coverage, above 85% minimum).
GORM scan: 0 CRITICAL/HIGH findings.

* docs: update ARCHITECTURE.md and features.md for stats subsystem

* feat(api): add stats handler and WebSocket hub for dashboard stats

* test: fix patch coverage for stats subsystem

Adds targeted tests to cover all previously uncovered patch lines:

Backend:
- stats_ws_hub_test.go (new): full hub coverage — constructor, non-blocking
  broadcast, ctx cancel exit, client broadcast, slow-client drop, client
  unregister, StatsWS upgrade-error path, StatsWS nil-hub close
- stats_handler_test.go: error-path 500s for all six handlers, non-integer
  within_days → 400, invalid limit param silently ignored
- stats_ingester_test.go: Stop flushes batches > batchSize; Run drains big
  batch on ctx cancel (covers batchSize branch in drain loop)
- stats_service_test.go: GetTrafficVolume 6h and 1d buckets; GetSummary DB error

Frontend:
- StatusDistributionChart: extended recharts mock calls Pie label/Tooltip
  content; adds 1xx test to cover statusClass "other" return
- TrafficVolumeChart: mock calls YAxis tickFormatter with MB/KB/B values
  and Tooltip content to cover formatBytes branches
- TopHostsChart: mock calls Tooltip content including hostname ?? label fallback
- CertExpiryList: adds undefined-data test to cover (data ?? []) branch
- useStatsWebSocket: adds non-stats_update message test for the else branch

* feat(frontend): add widget tooltips, top-hosts color coding, and hide/show controls

Adds ELI5 info tooltips to all 6 dashboard stats widgets, a color-coded
legend for the Top Hosts chart, and a per-widget visibility toggle
persisted in localStorage so users can hide widgets they don't need.

* fix(frontend): add aria-expanded to sidebar accordion buttons

Adding the Dashboard "Customize" button (which also carries
aria-expanded) shifted DOM order and caused the WebKit navigation E2E
test to target it instead of the sidebar, since the sidebar's
collapsible accordion buttons never actually exposed aria-expanded.
Add the missing attribute to the real sidebar toggles and scope the
test to the sidebar so it tests what it claims to.

* fix(api): join proxy_hosts to populate Top Hosts hostname

GetTopHosts only selected host_id and a count, never the hostname, so
every entry in the Top Hosts legend and tooltip rendered with a blank
or duplicate label. With every chart category collapsing to the same
empty string, Recharts merged the bars and hovering any bar showed the
same (highest) data point. Join proxy_hosts by UUID to populate the
real hostname, falling back to host_id if the host has since been
deleted.

* fix(database): run SQLite integrity check in background to avoid blocking startup

PRAGMA quick_check was running synchronously in Connect() and could take
well over a minute on larger databases (observed 93.5s), despite being
intended as a non-blocking, warn-only check.

* fix(database): give startup integrity check its own connection

The previous fix moved PRAGMA quick_check to a goroutine, but the main
pool is capped at one connection (SQLite single-writer constraint), so
the background check still held that connection for the full scan and
blocked AutoMigrate behind it. Open a dedicated connection for the
check so it no longer serializes against the rest of startup.

* fix(api): use proxy host Name instead of domain names for Top Hosts

GetTopHosts joined proxy_hosts.domain_names, showing raw domains in
the legend/tooltip instead of the user-assigned host Name. Switch the
join to proxy_hosts.name to match what users configured.

* fix(database): silence record-not-found noise in GORM query logs

Optional lookups (e.g. caddy.keepalive_idle/keepalive_count settings)
return ErrRecordNotFound when unset, which call sites already handle
via `if err == nil` fallbacks. GORM's default logger still logged
these as errors on every startup. Configure IgnoreRecordNotFoundError
so only real query errors and slow queries are logged.

* fix(api): match Top Hosts by domain instead of ProxyHost UUID

RequestLog.HostID stores the raw Host header seen by the proxy (a
domain), not the ProxyHost UUID, so the previous join on
proxy_hosts.uuid = request_logs.host_id never matched and silently
fell back to showing the domain. Build a domain -> name lookup from
proxy_hosts.domain_names (which can hold several comma-separated
domains per host) and resolve hostnames against that instead.

* feat(stats): add warmup guide and improve empty state UX

- Log successful LogWatcher startup with path info
- Add deployment/warmup guide for stats feature (docs)
- Improve TrafficVolumeChart empty state with helpful messaging
- Add data collection info to tooltip when no data available

* test(TrafficVolumeChart): update empty state text assertions

* fix(stats): replace CSS variable with hex literal in TrafficVolumeChart

SVG presentation attributes cannot resolve CSS custom properties defined
as space-separated RGB triplets (Tailwind v4 token format). Replace
`var(--color-brand-500)` with `LINE_COLOR = '#3b82f6'` so Recharts
renders a visible line stroke.

Add unit tests asserting stroke is a valid hex value and tooltip renders
correctly. Add Playwright step verifying recharts-line-curve path exists
when data is present.

* fix(stats): add LineChart mock and update QA report for feature/stats

* test: fix recharts mock to drop importActual for Vitest ESM compat

* chore(deps): bump go-toml to v2.4.0 and prometheus/common to v0.69.0

---------

Co-authored-by: GitHub Actions <actions@github.com>

* fix(deps): resolve js-yaml and markdown-it DoS vulnerabilities via npm overrides

Force js-yaml to >=4.2.0 and markdown-it to >=14.2.0 via npm overrides to address
GHSA-h67p-54hq-rp68 and GHSA-6v5v-wf23-fmfq in markdownlint-cli2 transitive deps.
Also correct lint:md scripts to use valid markdownlint-cli2 negated glob syntax
instead of the unsupported --ignore flag.

* fix(ci): align trivyignores and upload-sarif SHA across scan workflows

Add trivyignores: '.trivyignore' to the main-image table and SARIF Trivy
scan steps in docker-build.yml so suppressed CVEs are excluded from both
log output and SARIF uploads, consistent with the PR scan steps.

Align the upload-sarif action SHA in security-pr.yml from the stale
pre-v4.36.2 pin to the canonical 8aad20d SHA (v4.36.2) used by every
other security workflow in this repository.

* fix(ci): add post-upload SARIF verification to weekly security rebuild

Add trivyignores: '.trivyignore' to the SARIF scan step in
security-weekly-rebuild.yml so accepted/pending CVE suppressions are
excluded from the weekly Security tab upload, matching all other scan
workflows.

Add id: upload-trivy-weekly to the upload step and a new
'Verify SARIF was uploaded' step that validates the SARIF file exists,
that the upload succeeded, and that the file is parseable JSON. Fails the
workflow visibly instead of silently discarding SARIF upload errors,
preventing the pipeline from going stale undetected as happened Feb-May 2026.

* chore: bump mongo-driver/v2 from v2.6.1 to v2.7.0

* chore(deps): bump frontend lockfile dependencies

* chore: add package package-lock.json

* chore(deps): bump lucide-react from 1.20.0 to 1.21.0

* chore: bump go-sqlite3 from v1.14.45 to v1.14.46

* chore(deps): bump moby/moby client to v0.5.0 and api to v1.55.0

* chore: bump nanoid to 3.3.13 and yargs to 16.2.2

* chore(deps): bump eslint-plugin-sonarjs to 4.1.0

* chore(frontend): remove autoprefixer from postcss config

* fix(frontend): remove unused autoprefixer dependency

* fix: wrap webkit scrollbar styles in @supports selector guard

* chore: bump @types/node from 25.9.3 to 26.0.0

* chore(deps): bump @types/node to v26 and eslint-plugin-unicorn to v68

* chore(renovate): add gomodTidy, fix golang-jwt/jwt v5 tracking

* chore(deps): bump react-hook-form from 7.79.0 to 7.80.0

* chore(deps): update github-actions-non-major (#1086)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>

* chore(deps): update node.js to v24.17.0 (#1088)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>

* fix(deps): correct react-hook-form 7.80.0 integrity hash in lockfile

The react-hook-form@7.80.0 tarball was republished on the npm registry
after the package-lock.json was generated, producing a different SHA-512
digest. npm ci --ignore-scripts in the Docker Alpine build layer failed
with EINTEGRITY because the stored hash no longer matched the served tarball.

Updated the integrity field from the stale sha512-mhYp/... to the current
sha512-4P+fk6... value, which resolves the Docker build failure.

* chore(deps): update dockerfile-non-major to v1.77.0 (#1087)

* chore(deps): update dockerfile-non-major to v1.77.0

* fix: eliminate TempDir cleanup race in database tests

runQuickCheck ran as an untracked goroutine, leaving WAL/SHM file
handles open when t.TempDir() cleanup fired, causing intermittent
"directory not empty" failures.

Introduce launchQuickCheck (defaults to the goroutine) so tests can
override it to run synchronously via TestMain, ensuring the integrity
check connection is closed before temp dirs are removed.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>
Co-authored-by: GitHub Actions <actions@github.com>

* chore(deps): update go-non-major to v1.4.0 (#1090)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>

* chore(deps): update actions/checkout action to v7 (#1089)

* chore(deps): update actions/checkout action to v7

* fix(auth): ensure server-side session is invalidated before local state clears on logout

The logout() function in AuthContext was clearing React/localStorage state
before the backend POST /auth/logout completed. Because the onClick handler
never awaits the returned Promise, React redirected to /login (and Playwright's
waitForURL resolved) while the session_version increment and cookie-clearing
were still in-flight. Any immediate check against /api/v1/auth/me would receive
200 via the still-valid auth_token cookie (Firefox accepts Secure cookies on
http://127.0.0.1), causing the E2E "Session isolation after logout and re-login"
test to fail consistently.

Fix: call the backend first (cookie still authenticates it), then clear local
state in a finally block so local and server-side state are always consistent.

Also fix a flaky Playwright test ("User cannot promote self to admin") where
page.goto('/users') raced with Login.tsx's pending invalidateQueries→navigate('/')
chain. Adding waitForURL+waitForLoadingComplete after loginWithCredentials
ensures the app settles on the dashboard before navigating.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>
Co-authored-by: GitHub Actions <actions@github.com>

* chore: bump nanoid from 3.3.13 to 3.3.14

* chore: bump nanoid from 3.3.13 to 3.3.14

* chore(dep): update package rules for js-yaml

* chore(docker): update GeoLite2-Country.mmdb checksum (#1091)

Automated checksum update for GeoLite2-Country.mmdb database.

Old: 11b88595d026953920668d91f6d531057b397f05170237fc98a13a8b051ab861
New: 6e9212f23d3279a2454404d3b2a7ac30159fddbb9870ba33763014877296455c

Auto-generated by: .github/workflows/update-geolite2.yml

Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>

* chore(frontend): bump dependencies to latest versions

* chore: bump nanoid to 3.3.15 and smol-toml to 1.7.0

* chore: add Claude worktree isolation settings

* chore(deps): bump go-sqlite3 to v1.14.47 and modernc/sqlite to v1.53.0

* chore(dep): move js-yaml to ignoreDeps — packageRule didn't cover overrides entries

Renovate doesn't apply allowedVersions constraints to npm overrides blocks,
so the prior packageRule wasn't preventing v5 proposals. Moving js-yaml to
ignoreDeps silences Renovate entirely; the overrides pin in package.json
already locks it to ^4.2.0.

Also adds .claude/settings.json to disable background-session worktree
isolation (CLAUDE.md prohibits worktrees in this repo).

* chore(deps): bump go-toml/v2 from v2.4.0 to v2.4.1

* feat(theme): comprehensive theme system + FOUC fix (closes #34) (#1092)

* fix(theme): migrate CSS to data-theme selectors and update Tailwind config

* fix(theme): replace useLayoutEffect with useEffect + data-theme attribute; fix FOUC

- Move inline theme script to last in <head> via Vite plugin so stylesheet loads first (AC-02)
- Switch from classList.add to setAttribute('data-theme', ...) to avoid forced layout (AC-03)
- Replace useLayoutEffect with useEffect + useRef first-render skip in ThemeProvider (AC-04)
- Expand ThemeContextValue with full ThemeId, CustomTheme, ThemeExport types
- Add BUILT_IN_THEMES, BUILT_IN_THEME_LABELS, THEME_STORAGE_KEY, CUSTOM_THEME_STORAGE_KEY
- Add setTheme, resolvedTheme, customTheme, setCustomTheme, exportTheme, importTheme to context
- Fallback migration: reads old 'theme' key if 'charon-theme' not set (AC-12)
- ThemeToggle now navigates to /settings/appearance instead of binary toggle
- Add Appearance nav item to Settings page
- Add settings.appearance i18n key to all 5 locale files
- New ThemeContext.test.tsx with TC-01 through TC-13 scenarios
- Extend useTheme.test.tsx with happy-path and new API coverage
- Update Settings.test.tsx to include Appearance in nav order assertion

* feat(theme): add Settings Appearance tab, theme gallery, and preview

- Add ThemeGallery, ThemeCard, ThemePreviewOverlay components under
  frontend/src/components/theme/
- ThemeGallery renders 6 cards (5 built-ins + system) with role="radiogroup"
  and role="radio" accessibility attributes per WCAG 2.1 SC 4.1.2
- ThemeCard shows mini color swatches, handles hover/focus preview events,
  and keyboard selection (Enter/Space)
- ThemePreviewOverlay transiently sets data-theme on <html> without committing
  to context; restores resolvedCurrentTheme on null
- AppearanceSettings page at /settings/appearance with race-condition-safe
  handleThemeChange (setPreviewTheme(null) before setTheme)
- Add appearance route to App.tsx lazy routes
- Add all appearance.* i18n keys to en/de/es/fr/zh locale files
- 50 unit tests across 4 test files covering TG-01 through TG-06 scenarios

* feat(theme): add custom color picker and theme import/export

Add CustomColorPicker component with hex↔RGB conversion helpers and
10 color token inputs plus a color scheme toggle. Add ThemeImportExport
component with CSS injection-safe validation (RGB_PATTERN + VALID_THEME_IDS).
Extend AppearanceSettings to show the custom picker when theme=custom
and the import/export section always.

* feat(theme): add logo customization — backend upload endpoint and frontend UI

- Add LogoHandler (POST/DELETE /api/v1/settings/logo) with server-side MIME
  detection via net/http.DetectContentType; MaxBytesReader enforced at 2MB;
  SVG uploads rejected; filename always normalized to logo.<ext>
- Update NewRouter to accept dataDir and serve /uploads static directory
- Register logo routes in routes.go; derive dataDir from cfg.DatabasePath
- Add uploadLogo/deleteLogo to frontend settings API client
- Add LogoCustomizer component with Upload/URL tabs and admin-only guard
- Update AppearanceSettings with logo section using React Query mutations
- Update Layout.tsx to read ui.logo_url from settings and use as logo src
- Tests: BL-01..BL-07 backend, LC-01..LC-08 frontend, settings API tests

* test(e2e): add Playwright theme system E2E tests + docs updates

Adds theme.spec.ts covering FOUC fix, default theme, localStorage
persistence, system mode, gallery UI, preview-on-hover, custom color
picker, export/import, and logo customization. Updates ARCHITECTURE.md,
docs/features.md, and docs/features/ui-themes.md to reflect the new
data-theme CSS custom properties system.

Closes #34

* feat(theme): add banner upload endpoint and named themes backend CRUD

- Extract shared ImageUploadHandler with AssetConfig to DRY up image upload logic
- Refactor LogoHandler to delegate to ImageUploadHandler (zero API changes)
- Add BannerHandler for POST/DELETE /api/v1/settings/banner (admin-only)
- Add CustomTheme GORM model with UUID BeforeCreate hook and uniqueIndex on Name
- Add CustomThemeHandler with full CRUD: GET/POST /themes, PUT/DELETE /themes/:id
- Wire banner and theme routes into management group in routes.go
- Add CustomTheme to AutoMigrate list
- All logo_handler_test.go tests pass unchanged

* feat(theme): add banner customizer and named user themes frontend

Integrates banner upload/preview/delete UI with BannerCustomizer component,
and introduces UserThemeManager for creating, applying, editing, and deleting
named custom themes. Updates ThemeContext, ThemeContextValue, AppearanceSettings,
Layout, LogoCustomizer, ThemePreviewOverlay, settings API, and all i18n locales.
Adds full unit test coverage for new hooks (useUserThemes) and components.

* docs(theme): document banner upload and named custom themes in features.md

* test(theme): add E2E tests for banner upload and named user themes

Covers the two new Appearance settings features:
- Banner: upload PNG via file input, preview, sidebar display, URL-based
  save, and reset to default
- User themes: create via dialog, activate (verifies data-theme="custom"),
  edit name via PUT /api/v1/themes/:id, delete with confirmation dialog

Root-cause notes discovered during implementation:
- Backend stores theme colors as a JSON string; page.request must pass
  colors as JSON.stringify(colorsObj), not a plain nested object
- ThemeContext maps all user:* ThemeIds to data-theme="custom" on <html>,
  not to the raw user:<uuid> string
- All routes live under /api/v1/ (not /api/)

* fix(theme): update test mocks for ThemeContext useUserThemes dependency and banner API

- Mock useUserThemes in ThemeContext, ThemeImportExport, and AppearanceSettings
  tests so ThemeProvider does not require QueryClientProvider
- Add uploadBanner/deleteBanner to AppearanceSettings settings API mock

* test(theme): add backend coverage tests for error paths in custom theme and image upload handlers

- ListThemes, CreateTheme, UpdateTheme, DeleteTheme: add DB-closed error path tests
- UpdateTheme: add tests for malformed body, name > 100 chars, invalid colors JSON, duplicate name on rename
- BannerHandler: add JPEG upload test (covers acceptedMIME JPEG branch) and DB-closed test (covers upsertSetting error path)

* chore(deps): bump go-sqlite3, go-toml, and modernc/sqlite

* fix(e2e): update theme-fouc spec to use data-theme attribute instead of className

The inline anti-FOUC script now sets data-theme="dark"|"light" on <html>
(via setAttribute) rather than classList.add('dark'|'light'). Update T1-T5
to capture and assert the data-theme attribute at DOMContentLoaded, and
update T4 to verify the attribute before the background-color check.

T6 is rewritten: ThemeToggle no longer directly toggles the theme — it
navigates to /settings/appearance. The test now verifies the button title
and navigation target instead of a synchronous class change.

beforeEach now clears both 'theme' and 'charon-theme' localStorage keys
since the inline script reads from 'charon-theme' first.

* chore(deps): bump frontend dependencies to latest versions

* test(coverage): add patch coverage tests to reach 90% overall threshold

Frontend:
- ThemeToggle.test.tsx (new): onClick navigates to /settings/appearance,
  icon/aria-label reflect resolvedTheme — covers ThemeToggle.tsx:14
- LogoCustomizer.test.tsx: LC-09 invalid URL shows HTTPS error (covers
  lines 72-73), LC-10 switching URL→Upload tab re-shows file input
  (covers line 117); add logoUrlHttpsRequired to i18n mock
- BannerCustomizer.test.tsx: BC-12 switching URL→Upload tab re-shows file
  input (covers line 119)
- ThemeImportExport.test.tsx: simulate non-string FileReader result
  triggers error toast (covers lines 96-97)

Backend:
- server_test.go: TestNewRouter_WithDataDir verifies /uploads is served
  when dataDir is set (covers server.go:23-24); add SPA fallback test

Overall patch coverage: 89.1% → 90.8%

* chore: add Claude Code settings with enabled plugins

* fix(html): add explicit semicolons in FOUC script to satisfy CodeQL ASI rule

* fix(e2e): remove unused imports in theme.spec.ts to resolve CodeQL finding

* fix(e2e): rewrite theme-fouc spec to eliminate unreliable DOMContentLoaded listener

The DOMContentLoaded listener capture via addInitScript consistently returns
empty string in CI across all three browsers. Root causes:

1. Listener timing: the initScript's DOMContentLoaded listener races with the
   browser's fast headless page load; the attribute is null when the event
   fires, collapsing to '' via the ?? '' fallback.

2. Wrong localStorage key: T2-T5 used the old 'theme' fallback key instead of
   the primary 'charon-theme' key. The inline script reads charon-theme first,
   so setting only the fallback is unreliable when storageState may already
   contain a charon-theme value from the auth session.

Fix: remove the DOMContentLoaded listener entirely. Navigate to '/' with
{ waitUntil: 'domcontentloaded' } and read the attribute directly via
page.evaluate(). At domcontentloaded React's useEffect has not fired, so if
data-theme is set correctly it was set by the inline script — the FOUC proof
is preserved. Update all tests to use the charon-theme key.

* fix(security): suppress CVE-2026-39824 (GO-2026-5024) in Trivy and Grype

golang.org/x/sys/windows.NewNTUnicodeString integer overflow (CWE-190).
Go vulndb considers this fixed at v0.44.0; we ship v0.46.0 (above threshold).
The affected function is Windows-only — Charon is a Linux-only deployment and
this code path is never executed. NVD currently shows "no confirmed patch",
causing a discrepancy with Trivy v0.71.2+; govulncheck and Trivy v0.52.2
(fresh DB 2026-06-23) both report clean. No x/sys > v0.46.0 exists yet.

- .trivyignore: suppress CVE-2026-39824 with exp: 2026-09-23
- .grype.yaml: suppress GO-2026-5024 + CVE-2026-39824 with full justification
- .claude/settings.json: fix JSON syntax error (missing comma between keys)

Review: 2026-09-23 — remove once x/sys v0.47.0+ ships or NVD/Trivy converge.

* test(theme): add targeted tests to raise patch coverage from 90.8% to 95.4%

- backend logo handler: add error-path tests for empty file, MkdirAll
  failure, and read-only uploads directory
- settings API: add uploadBanner and deleteBanner unit tests
- UserThemeManager: add UTM-12 through UTM-17 covering dialog type,
  cancel, save, and edit flows
- ThemeContext: add 5 new tests covering user-theme loading guard,
  fallback-to-dark, system media query change, setUserTheme tokens,
  and activeUserTheme lookup
- AppearanceSettings: add mutation trigger tests for URL save, reset,
  custom color change, and UserThemeManager onActivate callback

---------

Co-authored-by: GitHub Actions <actions@github.com>

* chore: bump tldts, axe-core/playwright, and vite dependencies

* chore(frontend): bump frontend dependencies to latest versions

* chore: bump playwright from 1.61.0 to 1.61.1

* chore(deps): update dockerfile-non-major (#1095)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update actions/cache action to v6 (#1096)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* test: increase login redirect timeout to 15s for Firefox CI

* chore(deps): update github-actions-non-major (#1094)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>

* chore(deps): update node.js to v24.18.0 (#1097)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>

* chore: bump electron-to-chromium from 1.5.377 to 1.5.378

* fix: use axios for session validation to fix Firefox E2E auth test

Playwright's Firefox CDP network interception has known timing issues
with native fetch() during page.goto() navigation, while XHR (axios)
is intercepted reliably in all browsers.

`fetchSessionUser` used a raw fetch('/api/v1/auth/me') call, which
meant the Playwright route intercept in the Firefox session-expiry test
could let the auth check succeed against the real server instead of
returning the mocked 401. This prevented the redirect to /login from
firing, causing the test to fail consistently.

Switch to `client.get('/auth/me')` so all API calls go through the same
axios instance. The existing interceptor already excludes /auth/me from
triggering onAuthError, so the catch-block in checkAuth handles the 401
as before.

Also increase the success-modal visibility timeout in caddy-import-gaps
from the global 5s default to 10s to address Firefox CI flakiness where
React state updates after a commit response can take >5s.

* chore: bump rolldown to 1.1.3 and napi-rs/wasm-runtime to 1.1.6

* chore(deps): bump i18next to 26.3.2 and rolldown to 1.1.3

* chore(deps): bump go-toml/v2 from v2.4.1 to v2.4.2

* chore: update npm overrides deps in npm_update.sh

Handle flat and nested override entries separately to avoid ncu
crashes; add targeted typescript-only pass for frontend module.

* chore: ignore tempCodeRunnerFile.sh in scripts directory

* chore: pin js-yaml to ^5 in npm update script

* chore: bump knip to 6.19.0 and smol-toml to 1.7.0

* chore(deps): update npm-non-major (#1098)

* chore(deps): update npm-non-major

* fix: restore missing vite@8.1.0 entry in frontend lock file

Renovate's lock file regeneration omitted the node_modules/vite
resolved entry while updating the packages specifier to ^8.1.0,
causing npm ci to fail with "Missing: vite@8.1.0 from lock file".

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: GitHub Actions <actions@github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>

* chore(deps): update npm-non-major (#1099)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update node.js to v24.18.0 (#1101)

* chore(deps): update node.js to v24.18.0

* fix: revert node image to 24.16.0-alpine3.24 with valid multi-arch digest

node:24.18.0-alpine3.24@sha256:eb37f58646... was published to Docker Hub
today with an empty OCI image index (zero platform entries), making it
unpullable on any platform. All node:24.18.x tags share this broken
digest, indicating a Docker Hub publishing failure for that release.

Revert to node:24.16.0-alpine3.24@sha256:fb71d01... which has 6
confirmed platform manifests (linux/amd64, linux/arm64, s390x) and
produces a successful docker build --target frontend-builder.

* fix: upgrade node image to 24.17.0 and patch undici CVE-2026-12151

node:24.16.0-alpine3.24 carries two HIGH CVEs:
- CVE-2026-45447: OpenSSL heap-use-after-free in libcrypto3 (fixed in 3.5.7-r0)
- CVE-2026-12151: undici DoS via unbounded memory (fixed in undici 6.27.0)

node:24.17.0-alpine3.24 resolves the OpenSSL CVE via apk upgrade and ships
a valid 6-platform manifest (linux/amd64, linux/arm64, s390x), making it the
highest patched Node 24 image with a working multi-arch index.

node:24.18.0 was published to Docker Hub with an empty OCI manifest index
(zero platform entries) — a Docker Hub publishing failure — so it cannot
be used until Docker Hub resolves the issue.

Patch the remaining undici CVE-2026-12151 via targeted npm install -g,
following the same pattern as the existing picomatch CVE patch. Remove
both patches once a Node 24 image ships with undici >=6.27.0.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: GitHub Actions <actions@github.com>

* chore(deps): update github-actions-non-major (#1100)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore: bump @types/node from 26.0.0 to 26.0.1

* chore: bump go-pkcs12 from v0.7.2 to v0.7.3

* chore(deps): update node.js to v24.18.0 (#1102)

* chore(deps): update node.js to v24.18.0

* chore: update node frontend-builder image digest

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>
Co-authored-by: GitHub Actions <actions@github.com>

* chore(deps): bump eslint-plugin-unicorn from 68 to 69

* chore(deps): update dockerfile-non-major (#1103)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(deps): update module gorm.io/gorm to v1.31.2 (#1105)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update release-drafter/release-drafter digest to 73b95fa (#1104)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): bump frontend dev dependencies to latest versions

* chore: bump tar to 7.5.17 and expect-type to 1.4.0

* chore: bump es-to-primitive from 1.3.1 to 1.3.3

* refactor(scripts): merge go_update.sh and npm_update.sh into dep_update.sh

- Consolidate Go and npm update scripts into a single script
- Use repo-relative paths instead of hardcoded /projects/Charon
- Add type-check and test steps to npm update flow
- Allow npm audit fix and outdated to fail without aborting

* chore: remove test step from dep_update.sh module loop

* docs(security): add CVE-2026-39824 analysis and CHANGELOG entry

Document golang.org/x/sys vulnerability assessment confirming v0.46.0
already exceeds the v0.44.0 fix; Linux-only deployment excludes the
vulnerable Windows code path entirely. Includes govulncheck clean-scan
evidence and Trivy false-positive explanation.

* chore(deps): update module golang.org/x/vuln to v1.5.0 (#1107)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update release-drafter/release-drafter digest to 4d75298 (#1106)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): bump es-toolkit from 1.48.1 to 1.49.0

* chore(deps): update actions/cache digest to 55cc834 (#1108)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): bump modernc and golang.org/x indirect deps

* chore: bump prettier and analyze-trace to latest patch versions

* chore(deps): bump i18next, eslint, and knip to latest versions

* chore(deps): update dependency anchore/grype to v0.115.0 (#1109)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency anchore/syft to v1.46.0 (#1110)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jeremy <jhatfield82@gmail.com>

* chore: bump prometheus/procfs from v0.20.1 to v0.21.0

* chore: bump prettier to 3.9.1 and tar to 7.5.19

* chore(deps): bump react-query to 5.101.2 and knip to 6.22.0

* fix(renovate): add sourceUrl for prometheus/client_golang lookup

* chore(renovate): disable js-yaml auto-updates, managed manually

* chore(docker): update GeoLite2-Country.mmdb checksum (#1111)

Automated checksum update for GeoLite2-Country.mmdb database.

Old: 6e9212f23d3279a2454404d3b2a7ac30159fddbb9870ba33763014877296455c
New: 1522faf7b5f6a96c3a0128bca813bd4b0ae24dce38e9d37acdff0efaa75fcdd9

Auto-generated by: .github/workflows/update-geolite2.yml

Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>

* chore(deps): bump eslint-plugin-import-x and knip dev dependencies

* fix(ci): squash merge warning and safe PR number env var

---------

Co-authored-by: Jeremy <jhatfield82@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: GitHub Actions <actions@github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Wikid82 <176516789+Wikid82@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants