Commit Graph
100 Commits
Author SHA1 Message Date
Louis King cee487ef42 feat: hide users with test OIDC role from public views
Add OIDC_ROLE_TEST config var (default: 'test') to exclude test users
from dashboard stats, member counts, and the Members page. Uses
server-side filtering with exclude_test query param (default: true) and
client-side defense-in-depth filter in members.js.

- Add oidc_role_test to WebSettings in config.py
- Exclude test users from operator/member count queries in dashboard.py
- Add exclude_test param to GET /api/v1/user/profiles in user_profiles.py
- Filter test users client-side in members.js via role_names.test config
- Wire oidc_role_test into app.state and frontend config in web/app.py
- Document OIDC_ROLE_TEST in AGENTS.md and .env.example
2026-05-09 00:31:03 +01:00
JingleManSweep bbc51531b5 Merge pull request #204 from ipnet-mesh/fix/members-profile
fix: allow role-less OIDC users to save their own profile
2026-05-08 23:51:53 +01:00
Louis King 829971c174 fix: allow role-less OIDC users to save their own profile
The web proxy's endpoint access mapping previously required one of
(admin/operator/member) roles for PUT /api/v1/user/profile. This
blocked OIDC users with no assigned roles from saving their own profile.

Add an _AUTHENTICATED sentinel access level that grants access to any
logged-in user regardless of roles, and apply it to the profile PUT
endpoint. The API layer already enforces owner-only checks via
RequireUserOwner, so the proxy role gate was redundant.
2026-05-08 23:49:21 +01:00
JingleManSweep fbb2ebc9c6 Merge pull request #201 from ipnet-mesh/chore/prerelease-tidying
docs: sync documentation with source code before release
2026-05-06 19:26:04 +01:00
Louis King e034dfe81d docs: sync documentation with source code before release
Remove stale members.yaml references (post-members-refactor), add
missing env vars to AGENTS.md (API_HOST, WEB_HOST, CORS_ORIGINS,
NETWORK_*), fix project structure tree, add backward-compat note for
MQTT_TOPIC_PREFIX, and update nl.json/i18n.md members section.
2026-05-06 19:23:35 +01:00
JingleManSweep 3c343eb2fe Merge pull request #200 from ipnet-mesh/chore/markdown-parsing-map-filters
feat: improve markdown prose styling, map popup overlay, and collapsible filters
2026-05-06 19:04:56 +01:00
Louis King 9a65018235 chore: update web dashboard screenshot 2026-05-06 19:02:34 +01:00
Louis King 2f4a388a4c feat: improve markdown prose styling, map popup overlay, and collapsible filters
- Add .prose > :first-child margin-top:0 to eliminate double-spacing before headings
- Add nested list CSS (circle/square bullets, lower-alpha/roman numbering)
- Replace map popup <p>/space-y-1 layout with CSS grid for aligned label-value pairs
- Convert map filter card to collapsible <details> with state persistence
- Add nested list HTML output tests and markdown features docs
2026-05-06 19:02:18 +01:00
JingleManSweep c43da6ddf1 Merge pull request #199 from ipnet-mesh/chore/fix-members-count-widget
fix: include operators in members count widget
2026-05-06 18:22:22 +01:00
Louis King 93b5558654 fix: include operators in members count on homepage widget 2026-05-06 18:06:28 +01:00
JingleManSweep 497cd8393e Merge pull request #198 from ipnet-mesh/feature/new-members-widget
feat: replace MeshCore card with Members widget and add footer branding
2026-05-06 15:14:59 +01:00
Louis King 981c49e7fa feat: replace MeshCore card with Members widget and add footer branding 2026-05-06 15:11:58 +01:00
JingleManSweep 8e577cdf40 Merge pull request #197 from ipnet-mesh/chore/update-radio-info-display
feat: replace flat radio config list with icon tile grid on homepage
2026-05-06 13:36:26 +01:00
Louis King 6167b24591 feat: replace flat radio config list with icon tile grid on homepage
Replace the label:value list in the Network Info panel with a 3×2 grid of
compact tiles, each showing a themed cyan icon, label, and value. Adds 5 new
SVG icon functions and a --color-radio CSS custom property with dark/light variants.
2026-05-06 13:33:24 +01:00
JingleManSweep 1efa3e1f7b Merge pull request #196 from ipnet-mesh/chore/fix-qr-code-z-index
fix: increase mobile dropdown z-index to render above QR code on node detail page
2026-05-06 12:37:30 +01:00
Louis King 2ea3e70ec7 fix: increase mobile dropdown z-index to render above QR code on node detail page 2026-05-06 12:35:18 +01:00
JingleManSweep 361d5f712a Merge pull request #195 from ipnet-mesh/chore/ui-feedback-20250505
feat: restructure mobile navbar and increase dropdown sizes
2026-05-05 22:27:01 +01:00
JingleManSweep a1f0b354b2 Merge branch 'main' into chore/ui-feedback-20250505 2026-05-05 22:25:11 +01:00
Louis King 9c3611059a feat: restructure mobile navbar — move hamburger to right, increase dropdown sizes
Move mobile hamburger menu from navbar-start to navbar-end so it stays
right-aligned regardless of logo width. Mobile nav items are now rendered
via JS (renderMobileNav) using icon functions instead of duplicated inline
SVGs. Increase dropdown widths (w-52→w-56), icon sizes (h-4→h-5), and add
larger mobile tap targets via CSS media query.
2026-05-05 22:23:16 +01:00
JingleManSweep 71493d3516 Merge pull request #193 from ipnet-mesh/feat/mobile-sort-time-default
feat: default nodes sort by last_seen + mobile sort controls
2026-05-05 19:30:44 +01:00
Louis King 8dc6ccdad0 feat: change default nodes sort to last_seen DESC and add mobile sort controls
- Change API and frontend default sort from name/asc to last_seen/desc
- Add mobileSortSelect() shared component for native select dropdown
- Add mobile sort select to nodes, advertisements, and messages pages
- Add i18n sort labels for all three list pages
- Update sort tests for new default with staggered timestamps
2026-05-05 19:28:28 +01:00
JingleManSweep 73469b714f Merge pull request #191 from ipnet-mesh/renovate/esbuild-0.x
chore(deps): update dependency esbuild to ^0.28.0
2026-05-05 18:43:41 +01:00
JingleManSweep 8cb5253b68 Merge pull request #192 from ipnet-mesh/renovate/node-24.x
chore(deps): update node.js to v24
2026-05-05 18:40:56 +01:00
JingleManSweep 8b148d2d69 Merge pull request #190 from ipnet-mesh/chore/caching-and-bundling
feat: add esbuild bundling with content-hash cache busting
2026-05-05 18:31:44 +01:00
Louis King 3057a4841b feat: add esbuild bundling with content-hash cache busting
Bundle SPA JavaScript with esbuild for production builds, generating
content-hashed filenames for immutable caching. Vendor assets (Leaflet,
Chart.js, QRCode.js) get SHA256-based query params. Locale JSON files
get a combined hash version. Falls back to unbuiltsources when dist/
is absent.
2026-05-05 18:27:41 +01:00
JingleManSweep cdc4f1810f Merge pull request #189 from ipnet-mesh/chore/sort-nodes-alpha
feat: add clickable sort controls to list pages + alpha sort default for nodes
2026-05-05 17:25:28 +01:00
Louis King 160ba6d5bf feat: add clickable sort controls to list pages with alpha default for nodes
Add sort/order query parameters to Nodes, Advertisements, and Messages
API endpoints. Nodes default to alpha-by-name (via COALESCE of name tag,
node name, public key). Ads and Messages default to newest-first.

Frontend adds sortableTableHeader() component with asc/desc toggle
indicators. Sort state is preserved in URL params, surviving
auto-refresh and pagination.
2026-05-05 17:05:54 +01:00
JingleManSweep 2e41f182be Merge pull request #188 from ipnet-mesh/chore/docs-update-v0.10
fix: correct NODE_CLEANUP_DAYS default and add missing env vars to docs
2026-05-05 14:30:35 +01:00
Louis King 28255261fb fix: correct NODE_CLEANUP_DAYS default from 7 to 30 and add missing env vars to docs
NODE_CLEANUP_DAYS source of truth in Pydantic Settings is 30, not 7. Fixed in README, .env.example, docker-compose.yml, and docker-source-guide.md. Also added missing OIDC_POST_LOGOUT_REDIRECT_URI, WEB_AUTO_REFRESH_SECONDS, NETWORK_DOMAIN to docker-compose.yml web service. Added WEB_LOCALE and WEB_DATETIME_LOCALE to AGENTS.md env vars list.
2026-05-05 14:27:52 +01:00
JingleManSweep 800c67bb1f Merge pull request #187 from ipnet-mesh/chore/ui-fixes-and-daisycss-build
fix: migrate form classes to DaisyUI v5 and redesign home hero buttons
2026-05-05 13:22:29 +01:00
Louis King 9718df3f97 fix: migrate form classes to DaisyUI v5 and redesign home hero buttons
- Replace removed form-control/label-text/label-text-alt with DaisyUI v5
  fieldset/fieldset-label equivalents in node-detail.js and map.js
- Switch JS error display from innerHTML+label-text-alt to
  textContent+classList hidden toggling
- Redesign home hero navigation buttons as square cards with section
  colors, border hover animation, and centered icons
- Move custom page links to a separate row with compact btn-outline style
- Remove deprecated btn-outline CSS overrides from app.css
2026-05-05 13:19:44 +01:00
JingleManSweep d994047203 Merge pull request #186 from ipnet-mesh/chore/improve-filter-options
feat: add observer multi-select and collapsible filters to list pages
2026-05-05 12:25:21 +01:00
Louis King 9af90efee4 feat: add observer multi-select and collapsible filters to list pages
- Add observer multi-select (<select multiple size=2>) to Advertisements and
  Messages filter bars, populated from /api/v1/nodes?observer=true
- Make all filter sections collapsible via <details> on Nodes, Advertisements,
  and Messages pages; collapsed by default, auto-expands when active filters
  exist, preserves open state across auto-refresh ticks
- Add backend observer=true|false query param to GET /api/v1/nodes for
  observer-only or non-observer-only node filtering via subquery
- Change observed_by in Advertisements/Messages API from single public_key
  to list[str] with .in_() for multi-select support
- Fix router.js and api.js to handle array query params (duplicate keys
  promoted to arrays, .append() per element)
- Fix createFilterHandler to use FormData.getAll() for multi-value support
- Replace DaisyUI form-control/label/label-text classes with Tailwind-native
  equivalents (flex flex-col gap-1, flex items-center py-1, opacity-80 text-sm)
  since DaisyUI CSS is tree-shaken from the build output
- Thicker collapsible border (border-2 border-base-content/25) visible in
  both light and dark themes
- Bottom-align Filter/Clear buttons via two-row form layout
- Move Observer filter to last position on Advertisements page
- Add filter_observer_label i18n key
- Add tests for observer=true node filtering and multi observer params
2026-05-05 12:22:52 +01:00
JingleManSweep 98efc9dd06 Merge pull request #185 from ipnet-mesh/chore/ui-fixes
fix: resolve mobile UI issues on members page and node detail
2026-05-04 11:02:35 +01:00
Louis King b84cc8894f fix: resolve mobile UI issues on members page and node detail
- Replace nested <a> tags in member cards with @click handlers to fix
  invalid HTML causing missing badge styles and double-navigation
  race conditions (NS_BINDING_ABORT) on mobile
- Add e.preventDefault() to @click handlers to prevent parent <a>
  activation
- Bump mobile dropdown z-index from z-[1] to z-50 so menu items
  render above QR code wrapper (z-20) on node detail hero section
- Blur active element after SPA navigation to dismiss DaisyUI
  :focus-within dropdown state
- Fix dashboard channel messages to show short date+time format
- Add overflow-x-auto to custom pages and node detail panels for
  mobile overflow
- Fix tag editor: hide type column on mobile, truncate key/value
  cells, show key in modal title instead of disabled input field
- Fix delete tag dialog using innerHTML for <strong> in i18n strings
- Fix tag add form not resetting after successful submit
- Add break-word and overflow-x-auto to prose tables in app.css
2026-05-04 11:00:04 +01:00
JingleManSweep ddbbe05e54 Merge pull request #184 from ipnet-mesh/feature/inline-node-tag-editor
feat: replace admin tag page with inline node tag editor
2026-05-03 21:28:29 +01:00
Louis King 27b9ec21f2 feat: replace admin tag page with inline editor on node detail
Replace the dedicated admin tag management page with inline tag editing
on the node detail page. Operators can now edit tags directly on nodes
they've adopted; admins retain unrestricted access.

Key changes:
- Remove admin SPA page (admin/index.js, admin/node-tags.js)
- Add inline tag editor to node-detail.js with add/edit/delete modals
- Replace RequireAdmin with RequireOperatorOrAdmin for tag API routes
- Add ownership check: operators restricted to adopted nodes only
- Add validate_and_coerce_tag_value for number/boolean coercion
- Remove unused bulk endpoints (copy, move, replace all)
- Use AbortController for event listeners to prevent accumulation
  on lit-html DOM reuse across re-renders
- Track Leaflet map instance at module scope for defensive cleanup
- Fix checkAuthResponse to only redirect on 401 (not 403)
- Update tests for new OIDC-based auth model
- Update en.json locale, i18n.md, upgrading.md, AGENTS.md
2026-05-03 21:25:53 +01:00
JingleManSweep 3b99aa1daf Merge pull request #183 from ipnet-mesh/chore/refactor-infra-node-handling
feat: replace role=infra tag with adoption-based infrastructure detection
2026-05-03 19:05:17 +01:00
Louis King 560eb0796a feat: replace role=infra tag with adoption-based infrastructure detection
Replace the role=infra NodeTag convention with UserProfileNode adoption
as the canonical infrastructure indicator across map, Prometheus metrics,
and alerting. Renames is_infra to is_adopted, infra_center to
adopted_center. Map icons change to blue (adopted) / green (normal),
with all adoption UI gated on OIDC_ENABLED. Adds meshcore_nodes_adopted
gauge and Alembic migration to clean up obsolete tags.
2026-05-03 19:02:05 +01:00
JingleManSweep c05518c7b9 Merge pull request #182 from ipnet-mesh/chore/ui-tweaks
feat: user profile description/url + members hero link + profile layout fix
2026-05-03 00:08:49 +01:00
Louis King 2309428ce7 fix: remove btn-bg override so members hero button hover matches border color 2026-05-03 00:04:04 +01:00
Louis King c1e27fe63e feat: add members link to homepage hero, fix profile callsign layout
- Add Members button to homepage hero after Messages, using
  --color-members palette for icon and border color
- Gated by features.members !== false (auto-disabled when
  OIDC_ENABLED=false via existing server-side override)
- Move callsign badge inline with name in profile view,
  matching Members card layout
2026-05-02 23:58:29 +01:00
JingleManSweep a450531270 Merge pull request #181 from ipnet-mesh/chore/ui-tweaks
feat: add description and url fields to user profiles, fix nullable field clearing
2026-05-02 23:35:45 +01:00
Louis King f2ea530c0f feat: add description and url fields to user profiles, fix nullable field clearing
- Add description (Text) and url (String 2048) columns to user_profiles
- Expose in all API schemas (Read, Public, Update, ListItem) and list/get/profile endpoints
- Update profile.js form: add description/url inputs, render on view page
- Update members.js: render description and URL link in member tiles
- Fix update handler: use model_dump(exclude_unset=True) for nullable fields
  while protecting name (set by IdP) from being cleared
- AnyUrl validation on update, converted to str for SQLite compatibility
- Add i18n keys (description_label/placeholder, url_label/placeholder)
- 7 new API tests covering description/url CRUD, URL validation, null-clearing,
  and name non-nullability
2026-05-02 23:33:25 +01:00
Louis King db1a6aa3d5 Link adopted-by user name to profile page on node detail
Add profile_id to AdoptedByUser API schema and populate it from
the backend so the SPA can link the adopter's name to their
/profile/{id} page. Style the link with text-primary to stand out
from the surrounding opacity-70 text.
2026-05-02 19:06:50 +01:00
JingleManSweep a358363c2f Merge pull request #180 from ipnet-mesh/chore/ui-refactoring
Refactor SPA frontend: eliminate inline SVGs, extract shared components
2026-05-02 16:55:31 +01:00
Louis King 5a8160da0e Refactor SPA frontend: eliminate inline SVGs, extract shared components and templates
- Add 4 missing icons to icons.js (iconSettings, iconLogout, iconPause, iconPlay)
- Replace 13 inline SVGs with icons.js functions across 5 files
- Remove 3 raw-string SVG helpers from components.js
- Rewrite renderAuthSection() to lit-html (was innerHTML)
- Add renderFilterCard() and renderStatCard() to components.js
- Adopt renderFilterCard() in nodes, messages, advertisements pages
- Extract sub-renderers from home.js (hero, stats, activity chart)
- Extract 5 modal dialogs from admin/node-tags.js
- Use renderStatCard() in home.js and dashboard.js
- Extract renderChartCards() helper from dashboard.js
2026-05-02 16:52:09 +01:00
JingleManSweep 4c4c2b4823 Merge pull request #179 from ipnet-mesh/feature/auth-improvements
Auth improvements: OIDC-gated member filter, profile page fixes, members refactor
2026-05-02 14:48:25 +01:00
Louis King 486178a471 Add OIDC-gated member filter to Nodes/Advertisements/Map pages, fix profile page issues
- Add member filter dropdown to Nodes, Advertisements, and Map pages
  (visible only when OIDC is enabled), showing profiles as
  "Name (Callsign)" format
- Add adopted_by query param to /map/data endpoint for server-side
  member filtering on the map
- Fix members feature flag: auto-disables when OIDC is disabled
- Fix profile page: remove duplicate adopted nodes section,
  extract renderMemberSince(), align form labels with fixed-width
  label column
- Add i18n keys: common.all_members, common.filter_member_label
- Add map endpoint adopted_by tests, update features tests
2026-05-02 14:43:55 +01:00
Louis King f42cf92664 Fixed map JS error 2026-05-01 00:22:24 +01:00
Louis King d37b30a05b Replace Member model with UserProfile-backed data
Remove the static Member model/table, CRUD API, YAML seed files, and
admin UI. Replace with UserProfile-driven members page that reads roles
from OIDC identity provider. Key changes:

- Drop members table, add roles column to user_profiles (Alembic migration)
- Add GET /api/v1/user/profiles (paginated, no user_id exposed)
- Add GET /api/v1/user/profile/me (auto-creates profile for current user)
- Replace member_id node tag filter with adopted_by (profile UUID)
- Members page now shows profiles grouped by operator/member roles
- Profile page supports public view (/profile/:id) and owner edit (/profile)
- Node detail page shows adoption card side-by-side with public key card
- Auto-create user profile during OIDC login callback
- Hide Adopted Nodes section for non-operator/admin users
- Add member since date to profile cards
- Add role badges and adopted node badges to member tiles
- Add antenna/users icons to Members page group headers
2026-04-30 20:57:26 +01:00
Louis King 378f04d183 Hide admin UI when OIDC is disabled 2026-04-30 00:56:55 +01:00
Louis King 38c792196f Auto-populate user profile name from IdP on first access
Proxy now injects X-User-Name header from session. Profile auto-creation
uses it as the initial name value. Existing profile names are never
overwritten.
2026-04-30 00:23:16 +01:00
Louis King 31418e6847 Add user profiles with node adoption via /v1/adoptions endpoint
Move adopt/release from profile routes to dedicated /v1/adoptions endpoint.
Node API now returns adopted_by field. Profile page shows read-only adopted
nodes. Node detail page has adopt/release buttons (operator adopts, admin
can release any). Admin release bypasses ownership check.
2026-04-30 00:07:49 +01:00
JingleManSweep 6a5a23845f Merge pull request #178 from ipnet-mesh/feature/oidc-oauth-support
Add OIDC/OAuth2 authentication for web dashboard
2026-04-29 12:57:58 +01:00
Louis King a14dbaec45 Add OIDC authentication section to README before Webhooks 2026-04-29 12:55:40 +01:00
Louis King a37971b05c Add docs/auth.md and update documentation cross-references
- Create docs/auth.md covering OIDC architecture, login flow, configuration,
  local development setup, and LogTo provider guide
- Remove direnv-specific quoting note from .env.example
- Clarify OIDC_DISCOVERY_URL auto-appends .well-known/openid-configuration
- Fix admin route references from /a/ to /admin/
- Add auth.md links to README.md and AGENTS.md doc lists
- Add docs/auth.md to AGENTS.md documentation sync rule
2026-04-29 12:50:50 +01:00
Louis King 2cb7a96294 Use replace mode for admin form handler navigations to prevent stale page
When form handlers navigate to the same URL (e.g. adding two tags in a row
produces the same &message=... URL), the router's same-URL check skipped
the re-render. Using replace=true bypasses the check and avoids polluting
browser history with repeated flash-message entries.
2026-04-29 00:50:55 +01:00
Louis King 2af8b281ea Add OPTIONS to API proxy, fix admin event listener accumulation, rename admin routes from /a/ to /admin/
- Add OPTIONS to the web API proxy route methods for CORS preflight support
- Fix event listener accumulation in admin/node-tags.js and admin/members.js
  using AbortController with cleanup functions returned to the SPA router.
  lit-html reuses DOM elements across re-renders, causing addEventListener
  calls to accumulate and fire multiple times per form submission.
- Rename admin routes from /a/ prefix to /admin/ for clarity
- Add debug logging for admin route access and OIDC role checks
- Move auth section in navbar after theme toggle
- Update tests and AGENTS.md accordingly
2026-04-29 00:45:45 +01:00
Louis King d1b6f0d0a7 Fix OIDC logout redirect and username display for LogTo
- Pass client_id in logout redirect so LogTo can validate post_logout_redirect_uri
- Add OIDC_POST_LOGOUT_REDIRECT_URI config option with fallback derivation
- Move session.clear() after logout_redirect() to allow state data save
- Add 'username' to strip_userinfo() name fallback chain (LogTo uses this)
- Strip quotes from OIDC_SCOPES and pass as list to Authlib (fixes direnv
  quoting issue where literal quotes were sent in the authorization URL)
- Add OIDC_POST_LOGOUT_REDIRECT_URI to config, app state, and docs
- Add INFO-level logging to callback and logout handlers for diagnostics
- Update .env.example, README.md, AGENTS.md, docs/upgrading.md
2026-04-28 22:44:01 +01:00
Louis King 02c0a8f1b7 Add OIDC/OAuth2 authentication via Authlib
Replace WEB_ADMIN_ENABLED with full OIDC support using Authlib.
Admin access now requires authenticated sessions with IdP-assigned
roles instead of an open toggle.

- Add authlib and itsdangerous dependencies
- Add OIDC settings to WebSettings (13 env vars)
- Create web/oidc.py module (OAuth registry, session helpers)
- Add /auth/login, /auth/callback, /auth/logout, /auth/user routes
- Gate API proxy writes to admin sessions when OIDC enabled
- Protect /a/ routes with session check (redirect to login)
- Add SessionMiddleware for signed session cookies
- Add renderAuthSection navbar component (login/avatar dropdown)
- Add 401/403 interceptor in api.js for auto-redirect
- Exclude /auth/ from SPA client-side router interception
- Render auth section after translations load (fixes raw key display)
- Add custom error pages for 500s (standalone HTML, no JS deps)
- Update docker-compose.yml to pass OIDC_* env vars to web container
- Update .env.example, README, AGENTS.md, upgrading.md, i18n.md
- Add auth.* and errors.* i18n keys
- Add 200 tests (OIDC, admin, error pages)
2026-04-28 17:36:44 +01:00
JingleManSweep 963dabbbd5 Merge pull request #177 from ipnet-mesh/chore/remove-header-auth-pattern
Remove header-based auth (ProxyHeadersMiddleware, is_authenticated config, OAuth2 SPA flows)
2026-04-28 13:36:47 +01:00
Louis King 9873aa202b Remove header-based auth (ProxyHeadersMiddleware, is_authenticated config, OAuth2 SPA flows)
Remove the reverse-proxy header authentication pattern (X-Forwarded-User,
X-Auth-Request-User, Basic auth forwarding) from the web dashboard. Admin
access is now controlled solely by the WEB_ADMIN_ENABLED flag.

- Remove web_trusted_proxy_hosts config field and ProxyHeadersMiddleware
- Remove _is_authenticated_proxy_request() and api_proxy() 401 guard
- Remove is_authenticated from SPA config JSON
- Remove OAuth2 login/sign-out UI from admin pages and router
- Remove auth_required i18n keys (en, nl)
- Remove auth-related tests and fixtures
- Delete docs/hosting/nginx-proxy-manager.md
- Update README, AGENTS.md, .env.example, docs/i18n.md, agents docs-sync refs

572 tests pass, pre-commit clean.
2026-04-28 13:33:52 +01:00
JingleManSweep 2cc76b853b Merge pull request #176 from ipnet-mesh/chore/observer-ux-tweaks
Update observer table: SNR/Path headers and value suffix cleanup
2026-04-26 14:53:07 +01:00
Louis King 51d7de9d88 Update observer table: SNR/Path headers and value suffix cleanup
- Rename SNR header to 'SNR (dB)', Path header to 'Hops'
- Remove ' dB' and ' hop/s' suffixes from column values
- Add i18n keys for snr_db and hops to en.json and docs/i18n.md
- Fix README ARM note: only 32-bit ARM unsupported, RPi 3/4/5 work
2026-04-26 14:50:28 +01:00
JingleManSweep 8139cbc17e Merge pull request #175 from ipnet-mesh/chore/fix-network-error-display
Preserve table content on API errors with header warning badge
2026-04-26 14:05:37 +01:00
Louis King 8dec688917 Preserve table content on API errors with header warning badge
Instead of replacing the entire table with an error alert on network
failures, the previous data now stays visible and a warning icon with
tooltip appears in the sub-header bar. The warning clears automatically
on the next successful poll.

Restructured page headers into title row + sub-header row (count,
auto-refresh, warning) for better mobile layout.
2026-04-26 14:03:26 +01:00
JingleManSweep e4655a6b59 Merge pull request #174 from ipnet-mesh/feature/improve-snr-path-visibility
Add observer detail rows with SNR/path data and UI polish
2026-04-26 13:05:10 +01:00
Louis King e867f0074a Add observer detail rows with SNR/path data and UI polish
- Add path_len column to event_observers table with Alembic migration
- Create shared observer_utils.py for building observer responses
- Extract SNR and path_len from LetsMesh uploads via normalizer
- Pass snr/path_len from all 4 handlers to add_event_observer()
- Add expandable observer detail sub-tables to messages and ads pages
- Rename Receivers column to Observers with updated i18n key
- Add satellite dish icon to observer badges and detail rows
- Add mobile card observer detail toggle
- Show full datetime tooltip on hover for relative times
- Hide Path column from advertisement observer tables (not populated)
2026-04-26 13:02:39 +01:00
JingleManSweep a0d59748f2 Merge pull request #172 from ipnet-mesh/chore/change-meshcore-links
Update MeshCore URLs to meshcore.io and tagline
2026-04-24 11:18:30 +01:00
Louis King 74901441f5 Update MeshCore URLs to meshcore.io and tagline
- Replace meshcore.dev and meshcore.co.uk with meshcore.io across all files
- Replace flasher.meshcore.co.uk with flasher.meshcore.io
- Update MeshCore tagline to 'Off-Grid, Open-Source Encrypted Messaging'
2026-04-24 11:15:23 +01:00
JingleManSweep 7f5650d3f5 Merge pull request #171 from ipnet-mesh/chore/fix-markdown-styling
Fix markdown table borders in custom content pages
2026-04-21 22:00:49 +01:00
Louis King 55eb54ba10 Fix markdown table borders in custom content pages
Use DaisyUI v5 prose CSS custom properties (--tw-prose-td-borders,
--tw-prose-th-borders, --tw-prose-quote-borders, --tw-prose-hr)
instead of color-mix(in oklch, ..., transparent) which produced
invisible borders due to oklch/transparent color space mismatch.
2026-04-21 21:58:13 +01:00
JingleManSweep 305df54e1b Merge pull request #165 from ipnet-mesh/renovate/tailwindcss-monorepo
Update tailwindcss monorepo to v4.2.4
2026-04-21 20:51:26 +01:00
JingleManSweep 0b9fa0cb2a Merge pull request #170 from ipnet-mesh/fix/traefik-priority
Add TRAEFIK_PRIORITY support for multi-instance deployments
2026-04-21 20:00:56 +01:00
JingleManSweep 2aefb428d9 Merge branch 'main' into fix/traefik-priority 2026-04-21 19:59:04 +01:00
Louis King 0938ba4fd0 Add TRAEFIK_PRIORITY support for multi-instance deployments 2026-04-21 19:58:42 +01:00
JingleManSweep 7d0126aa87 Merge pull request #169 from ipnet-mesh/fix/test-fixes
Fix test_collector_with_data_home_override by unsetting SEED_HOME env var
2026-04-21 19:53:41 +01:00
JingleManSweep 6177835065 Merge branch 'main' into fix/test-fixes 2026-04-21 19:47:15 +01:00
Louis King 6d8b7642b0 Fix test_collector_with_data_home_override by unsetting SEED_HOME env var 2026-04-21 19:45:44 +01:00
JingleManSweep d442c5f75e Merge pull request #168 from ipnet-mesh/fix/public-key-casing
fix: normalize public keys to lowercase to prevent tag/event mismatches
2026-04-21 19:35:01 +01:00
Louis King 0478bb00a1 fix: normalize public keys to lowercase to prevent tag/event mismatches
The LetsMesh normalizer stored public keys as UPPERCASE while the tag
importer stored them as lowercase, creating duplicate nodes for the same
device. Normalize all public keys to lowercase throughout:
- MQTT topic parsing (event, command, LetsMesh upload)
- LetsMesh normalizer output
- Node model __init__ enforcement
- Alembic migration to merge duplicates and normalize existing data
2026-04-21 08:50:38 +01:00
JingleManSweep 4887463515 Merge pull request #164 from ipnet-mesh/feature/ui-bundling
Replace all CDN dependencies with locally built vendor assets
2026-04-20 13:18:56 +01:00
Louis King 4f202c068b Replace all CDN dependencies with locally built vendor assets
- Add Node.js 22 LTS frontend build stage (package.json, build.js)
- Build Tailwind CSS v4 + DaisyUI v5 via CLI instead of runtime CDN
- Vendor lit-html, Leaflet, Chart.js, QRCode.js locally
- Update Dockerfile with multi-stage Node.js frontend build
- Migrate all DaisyUI v4 CSS variables to v5 syntax in app.css
- Fix dashboard grid layout (static class names for Tailwind JIT)
- Fix map popup transparent background (v5 variable rename)
- Fix leaflet.js.map 404 (include source maps in vendor copy)
- Fix custom page button contrast (remove btn-neutral)
- Replace table-compact with table-sm (DaisyUI v5 rename)
2026-04-20 13:16:13 +01:00
JingleManSweep 49bbcf1b7c Merge pull request #163 from ipnet-mesh/chore/fix-subdomains
More fixes
2026-04-19 23:05:14 +01:00
Louis King d43a15bab0 More fixes 2026-04-19 23:03:03 +01:00
JingleManSweep fed4f7ba34 Merge pull request #162 from ipnet-mesh/chore/fix-subdomains
Added subdomain support for web service
2026-04-19 22:46:46 +01:00
Louis King 14e2ead4d2 Added subdomain support for web service 2026-04-19 22:44:36 +01:00
JingleManSweep 0f86870ba6 Merge pull request #161 from ipnet-mesh/chore/fix-packetcapture-compose
Fixed Packet Capture Docker Compose
2026-04-19 22:16:46 +01:00
JingleManSweep 3d681fc2da Merge branch 'main' into chore/fix-packetcapture-compose 2026-04-19 22:15:00 +01:00
JingleManSweep fb4d01ac5c Merge pull request #159 from ipnet-mesh/chore/action-fixes-2
Updates
2026-04-19 22:14:27 +01:00
Louis King 846e12ce66 Fixed Packet Capture Docker Compose 2026-04-19 22:13:38 +01:00
Louis King 79ab4ee06f Updates 2026-04-19 21:58:43 +01:00
Louis King 5df308b6bc Updates 2026-04-19 21:56:59 +01:00
JingleManSweep 3567f86408 Merge pull request #156 from ipnet-mesh/chore/add-packet-capture-resources
Add observer Docker Compose setup and update README instructions
2026-04-19 21:55:37 +01:00
JingleManSweep 70ccafeb97 Merge pull request #158 from ipnet-mesh/chore/fix-actions
Updates
2026-04-19 21:55:06 +01:00
Louis King 0d6c79797e Updates 2026-04-19 21:52:10 +01:00
Louis King a587c93914 Normalize LetsMesh spelling in docker-compose comments 2026-04-19 21:49:23 +01:00
Louis King 710263b248 Add observer Docker Compose setup and update README instructions
Add contrib/packetcapture/ with ready-made docker-compose.yml and .env.example
for remote observers. Parameterize MQTT port and TLS for local network use.
Rewrite README observer section with wget-based setup workflow.
2026-04-19 21:47:57 +01:00
JingleManSweep 19ac2f8aa1 Merge pull request #155 from ipnet-mesh/chore/quick-fixes
Add content and webhooks docs links to README
2026-04-18 11:47:09 +01:00