Commit Graph
996 Commits
Author SHA1 Message Date
JingleManSweep bda6370cb0 Merge pull request #376 from ipnet-mesh/test/e2e-ui-regression-coverage
test(e2e): expand Playwright coverage for UI regression protection
2026-08-30 12:39:53 +01:00
JingleManSweep 4a4eb134d0 Merge branch 'main' into test/e2e-ui-regression-coverage 2026-08-30 12:37:54 +01:00
Louis King 47fa9c6749 test(e2e): fix selector and assertion bugs in the new specs
- channels: post-delete card count is 6 (6 seeded + 1 created - 1), not 5
- empty-states/pagination: the empty text renders twice (mobile
  EmptyState + desktop EmptyRow); scope assertions to the table cell
- mobile: list-row is desktop-only; assert the mobile sort select and
  card text instead
- not-found: '/$' is a glob, not a regex; assert the exact URL '/'
- packets-detail: the newest seeded packet is the ce01 message, not an
  advert; assert the event type returned by the API
2026-08-30 12:32:53 +01:00
Louis King ec199e4e2b test(e2e): expand Playwright coverage for UI regression protection
Grow the suite from 41 to 77 specs covering previously untested UI
surfaces: channels admin CRUD with QR codes and keyboard nav, node
detail adoption/tag editing with the role permission matrix, SPA 404
page, sortable tables with URL-synced sort state, pagination with
filter-preserving links, mobile viewport (hamburger nav, mobile cards,
sort select), anonymous/member auth gating, raw packet detail, and
empty states. Route cards now assert history chart, recent-match links
and owner profile links.

Supporting changes: purposeful data-testids on channels/node-detail/
pagination/sort headers (plus aria-sort) and mobile nav; seed_data adds
30 trace_data filler groups for pagination, channels at every
visibility tier incl. one disabled, and a pw-operator profile.
2026-08-30 12:27:48 +01:00
JingleManSweep 18e3eb88de Merge pull request #375 from ipnet-mesh/renovate/major-github-artifact-actions
chore(deps): update actions/download-artifact action to v8
2026-08-30 11:58:17 +01:00
renovate[bot] 9406ff4e1d chore(deps): update actions/download-artifact action to v8 2026-08-30 10:51:23 +00:00
JingleManSweep e67e0ec3ae Merge pull request #374 from ipnet-mesh/chore/ci-summary
ci: add consolidated job summary with test results and artifacts
2026-08-30 11:50:53 +01:00
Louis King 9f9cd67440 ci: add consolidated job summary with test results and artifacts
Add a summary job that runs after all CI jobs (even on failure),
parses the pytest/vitest/Playwright JUnit reports plus coverage.xml,
and renders a consolidated Markdown summary to $GITHUB_STEP_SUMMARY:
job results, test counts, durations, backend coverage, failure
details, and the artifact inventory. Enable a Playwright JUnit
reporter and include it in the playwright-report artifact.
2026-08-30 11:46:12 +01:00
JingleManSweep 8aa451d4b7 Merge pull request #373 from ipnet-mesh/fix/postgres-profile-dev-only
fix(compose): keep bundled postgres out of the core profile in production
2026-08-30 11:24:46 +01:00
Louis King 5a8794f5c9 fix(compose): keep bundled postgres out of the core profile in production
Starting core with docker-compose.prod.yml also started the bundled
postgres container, whose 'postgres' network alias shadowed a shared
instance of the same name on the same Docker network — the live site
silently talked to an empty local database instead of DATABASE_HOST.

- Base file: postgres profiles are now [all, postgres] (core dropped);
  the dev override unions 'core' back in, so the documented dev
  workflow (make up, --profile core) is unchanged
- migrate's postgres dependency is required: false — still health-gated
  when the bundled container is active, skipped when profile-inactive
- prod override documents the behavior; opt in explicitly with
  --profile postgres (or --profile all) for a bundled production DB
- Docs: database.md/deployment.md/configuration.md/README/.env.example
  updated; upgrading.md gains a one-time cleanup runbook (full down to
  remove the previously started hub-postgres container)
2026-08-30 11:22:08 +01:00
JingleManSweep c085e124eb Merge pull request #372 from ipnet-mesh/chore/ci-e2e-and-report-artifacts
Add Playwright e2e job to CI and upload test report artifacts
2026-08-30 11:05:35 +01:00
JingleManSweep 5f621d8036 Merge branch 'main' into chore/ci-e2e-and-report-artifacts 2026-08-30 11:02:56 +01:00
Louis King 3ca379c923 Add Playwright e2e job to CI and upload test report artifacts 2026-08-30 11:02:12 +01:00
JingleManSweep 562e54a2ff Merge pull request #371 from ipnet-mesh/docs/remove-sqlite-support-plan
Remove SQLite support; PostgreSQL is now the only database backend
2026-08-30 10:49:13 +01:00
Louis King 81dcd3dead Remove SQLite support; PostgreSQL is now the only database backend 2026-08-30 10:19:12 +01:00
Louis King 2c805f2ae1 Updates 2026-08-29 23:31:15 +01:00
JingleManSweep e87a002238 Merge pull request #370 from ipnet-mesh/fix/operational-hardening
fix: readiness 503s, maintenance gating, cache invalidation, and webhook/engine hardening
v0.18.0
2026-08-29 22:43:25 +01:00
Louis King 3f9669f7e5 fix: readiness 503s, maintenance gating, cache invalidation, and webhook/engine hardening
- /health/ready returns 503 (not 200) when not ready; body no longer leaks
  raw backend error text (api + web tiers)
- SYSTEM_MAINTENANCE now gates the web /api/* proxy (503 MAINTENANCE)
  instead of only hiding the SPA UI
- channel mutations invalidate messages/packets/packet_groups/dashboard
  caches so visibility/key changes apply immediately (was stale up to 1h)
- async DB engine: pool_size/max_overflow/pre_ping matching the sync
  engine (survives Postgres restarts); adispose() awaited from the API
  lifespan (async connections were leaked by the sync dispose)
- webhooks: permanent 4xx (except 408/429) fail fast instead of retrying;
  dispatch queue bounded at 1000 with drop-oldest + warning; shutdown
  logs dropped events; matches_event evaluated once
- SPA: apiGet/apiPostForm redirect to OIDC login on 401; chart date
  labels and route timestamps rendered in UTC/configured timezone
- e2e compose collector healthcheck uses 'meshcore-hub health collector'
  (image has no pgrep)
- docs/upgrading.md: fold unreleased notes into v0.18.0 and document the
  above
2026-08-29 22:40:19 +01:00
JingleManSweep d4cbfb63a4 Merge pull request #369 from ipnet-mesh/fix/correctness-bugs
fix: silent config drops, metrics event-loop stall, and route/decoder bugs
2026-08-29 22:13:04 +01:00
Louis King b23e7bcf15 fix: silent config drops, metrics event-loop stall, and route/decoder bugs
- api CLI single-process path now passes spam_detection_enabled /
  spam_score_threshold to create_app() so the messages hide-filter
  actually runs in the default (Docker) deployment
- OIDC role names (oidc_role_admin/operator/member/test) moved from
  WebSettings to CommonSettings and wired onto API app.state; the API
  tier previously matched hardcoded role names, ignoring customized
  OIDC_ROLE_* config in authz, channel visibility, and tag/adoption
  checks (oidc_roles_claim stays web-only)
- /metrics handler is now sync def so collection runs in the
  threadpool instead of blocking the event loop; hoisted fragile
  in-loop imports
- evaluate_route_history gates max_path_length on the packet's true
  hop count (RawPacket.path_len) instead of the prefix-filtered hop
  list, so history day buckets agree with snapshot evaluation
- reload_keys clears the decode cache: negatively-cached packets for
  a newly added channel key were permanently dropped by the normalizer

Also documents 'sudo npx playwright install-deps chromium' in the
AGENTS.md e2e setup.
2026-08-29 22:08:25 +01:00
JingleManSweep ee6e0c4894 Merge pull request #368 from ipnet-mesh/fix/security-hardening
fix(security): close fail-open defaults, header spoofing, and add CSP
2026-08-29 21:39:28 +01:00
Louis King dca3dcb309 fix(security): close fail-open defaults, header spoofing, and add CSP
- /map/data: resolve viewer OIDC session and apply the endpoint access
  mapping before fetching profiles; serve Cache-Control: private when
  OIDC is enabled (payload varies by viewer)
- /user/profile/me + /user/profile/{id}: trust X-User-Id only with a
  valid API key (new optional_user_identity dependency); closes the
  OIDC subject-identifier leak via forged headers
- OIDC_SESSION_SECRET is now mandatory when OIDC is enabled (hard fail,
  no insecure-dev-secret fallback)
- /metrics denies unauthenticated access when no API read key is set;
  new METRICS_PUBLIC opt-in (Settings, CLI, compose, env factory)
- CORS: unset CORS_ORIGINS keeps wildcard compat but drops
  allow_credentials (invalid combination in browsers) + warns
- Web tier: SecurityHeadersMiddleware (nosniff, X-Frame-Options DENY,
  Referrer-Policy, Permissions-Policy) + nonce-based CSP; nonce applied
  to spa.html inline scripts; WEB_SECURITY_HEADERS kill switch and
  WEB_CSP_EXTRA for custom tile hosts; API emits nosniff

Breaking changes documented in docs/upgrading.md.
2026-08-29 21:32:41 +01:00
JingleManSweep b751cf68b8 Merge pull request #367 from ipnet-mesh/fix/map-data-pagination
fix(web): paginate /map/data node and profile fetches
v0.17.3
2026-08-29 13:33:20 +01:00
Louis King 9b6a16d862 fix(web): paginate /map/data node and profile fetches
The map endpoint fetched a single limit=500 page (the API's hard max,
sorted last_seen desc), so networks with more than 500 nodes silently
hid stale/offline nodes from the unfiltered map — including adopted
infrastructure, which still appeared under the adopted_by filter
because that filter narrows the query before the limit applies.

Follow offset/total pagination via a new _fetch_all_pages helper (40
pages / 20k nodes safety cap, partial results on later-page failure)
for both /api/v1/nodes and /api/v1/user/profiles, and report the
API-reported total in debug.total_nodes.
2026-08-29 13:01:16 +01:00
JingleManSweep c9d5e86953 Merge pull request #365 from ipnet-mesh/renovate/anomalyco-opencode-1.x
chore(deps): update anomalyco/opencode action to v1.18.25
2026-08-29 11:39:51 +01:00
renovate[bot] 524b2f0445 chore(deps): update anomalyco/opencode action to v1.18.25 2026-08-29 10:37:00 +00:00
JingleManSweep 95e99a2278 Merge pull request #363 from ipnet-mesh/renovate/tanstack-query-monorepo
chore(deps): update dependency @tanstack/react-query to v5.102.8
2026-08-29 11:36:09 +01:00
JingleManSweep 972898cff5 Merge branch 'main' into renovate/tanstack-query-monorepo 2026-08-29 11:33:38 +01:00
JingleManSweep 191ccd07d1 Merge pull request #357 from ipnet-mesh/renovate/leaflet-1.x-lockfile
chore(deps): update dependency @types/leaflet to v1.9.22
2026-08-29 11:33:23 +01:00
renovate[bot] b1f71baf63 chore(deps): update dependency @tanstack/react-query to v5.102.8 2026-08-29 10:31:11 +00:00
renovate[bot] b2fd54cb83 chore(deps): update dependency @types/leaflet to v1.9.22 2026-08-29 10:31:04 +00:00
JingleManSweep b30f1231ec Merge pull request #355 from ipnet-mesh/renovate/vite-8.x-lockfile
chore(deps): update dependency vite to v8.2.2
2026-08-29 11:30:06 +01:00
renovate[bot] ae2caee41c chore(deps): update dependency vite to v8.2.2 2026-08-29 10:27:44 +00:00
JingleManSweep 2dd99f7f92 Merge pull request #364 from hardtofindg/hardtofindg-patch-1
docs: align README Python version
2026-08-29 11:26:30 +01:00
JingleManSweep 18cebeb5ea Merge branch 'main' into hardtofindg-patch-1 2026-08-29 11:19:42 +01:00
JingleManSweep 933ad756f2 Merge pull request #354 from ipnet-mesh/renovate/vitejs-plugin-react-6.x-lockfile
chore(deps): update dependency @vitejs/plugin-react to v6.1.1
2026-08-29 11:17:44 +01:00
renovate[bot] 24337a5374 chore(deps): update dependency @vitejs/plugin-react to v6.1.1 2026-08-29 10:14:58 +00:00
JingleManSweep 806b378261 Merge pull request #358 from ipnet-mesh/renovate/testing-library-monorepo
chore(deps): update testing-library monorepo
2026-08-29 11:13:35 +01:00
renovate[bot] b972a5def2 chore(deps): update testing-library monorepo 2026-08-29 10:11:13 +00:00
JingleManSweep 1e871d5c51 Merge pull request #366 from ipnet-mesh/renovate/react-router-monorepo
chore(deps): update dependency react-router to v8.3.1
2026-08-29 11:10:01 +01:00
renovate[bot] 64df1b3297 chore(deps): update dependency react-router to v8.3.1 2026-08-29 10:07:48 +00:00
JingleManSweep b74855ee01 Merge branch 'main' into hardtofindg-patch-1 2026-08-29 11:07:18 +01:00
JingleManSweep 8400fc524f Merge pull request #353 from ipnet-mesh/renovate/jsdom-30.x
chore(deps): update dependency jsdom to v30
2026-08-29 11:06:27 +01:00
JingleManSweep ceb4f2be52 Merge branch 'main' into renovate/jsdom-30.x 2026-08-29 11:03:57 +01:00
JingleManSweep e3bb6752a3 Merge branch 'main' into hardtofindg-patch-1 2026-08-29 11:03:29 +01:00
JingleManSweep 604ff06cb9 Merge pull request #356 from ipnet-mesh/renovate/react-monorepo
chore(deps): update react monorepo to v19.2.18
2026-08-29 11:02:48 +01:00
JingleManSweep 2afffedaf0 Merge branch 'main' into hardtofindg-patch-1 2026-08-29 11:02:00 +01:00
renovate[bot] 91bbd4e3f9 chore(deps): update react monorepo to v19.2.18 2026-08-29 09:58:14 +00:00
JingleManSweep 1a082edbb8 Merge branch 'main' into renovate/jsdom-30.x 2026-08-29 10:57:18 +01:00
JingleManSweep 08f74f1522 Merge pull request #351 from ipnet-mesh/renovate/daisyui-5.x-lockfile
chore(deps): update dependency daisyui to v5.7.22
2026-08-29 10:57:02 +01:00