[1.4.0] - 2026-07-05
Added
- Single sign-on via OpenID Connect (OIDC) — NetMap can now authenticate against any OIDC provider (Authentik, Authelia, Keycloak, Zitadel, Okta, Microsoft Entra ID, Google Workspace) using Authorization Code + PKCE. Configure via environment variables (
OIDC_ENABLED,OIDC_ISSUER,OIDC_CLIENT_ID, …) or in-app under Admin → Security → Single Sign-On (DB settings override env; the client secret is stored encrypted and is write-only in the API). The login screen gains a "Continue with SSO" button alongside the existing username/password form. Security baseline: signed ID-token verification via provider JWKS (asymmetric algorithms only), issuer/audience checks, state + nonce validation bound to the browser with a single-use server-side transaction, PKCE S256, verified-email enforcement, optional email-domain allowlist — and no provider tokens ever reach the browser; a successful callback issues the normal NetMap session cookies. Includes identity linking by provider subject with optional first-time linking by verified email, optional auto-provisioning with a conservative default role (never SuperAdmin), group/role claim mapping with local-role precedence by default and explicit opt-in for provider-managed roles or SuperAdmin grants, an Admin "Test provider" diagnostic action, per-user auth-source (SSO) badges in Admin → Users, audit events for every provision/link/login/settings change, and an optional "Require SSO" mode with guard rails (provider must verify and an active SuperAdmin must exist) that always preserves SuperAdmin local login as the emergency recovery path. Migrations0043_oidc_login_states,0044_external_identities. - Toast notifications — actions across the app (deletes, saves, imports) now confirm success or surface failures in a bottom-right toast stack instead of failing silently or relying on scattered inline text.
- Styled destructive-action confirmations — deleting devices, links, groups, locations, subnets, reservations, DHCP leases, schedules, roles, and saved searches now opens a consistent danger-styled dialog with consequence text; bulk device deletes of 5+ require typing
deleteto confirm. - Workspace crash containment — an unexpected error in one workspace now shows a retryable fault card while the rest of NetMap keeps working, instead of a white screen.
- Loading skeletons — workspaces show shimmer skeleton layouts while data loads (route changes, VLANs, IPAM) instead of blank panels or plain "Loading…" text.
- Response-time (RTT) threshold alert rules — Admin → Alerts now offers a "Response time above threshold" trigger with a configurable millisecond threshold (per device or fleet-wide). The background monitor fires the rule when a device's probe RTT exceeds the threshold, reusing the existing notification channels and cooldown; a persistent high-latency condition re-alerts once per cooldown period. Migration
0036_alert_rule_threshold_msaddsalert_rules.threshold_ms. - Pause monitoring per device — devices can be paused from the device form or the Pause/Resume button in device details. Paused devices are skipped by live/background probes (no false offline alerts), show a gray "paused" status in Monitoring (with a Paused filter and fleet paused count), and stay in inventory/topology. Migration
0037_device_monitoring_fields. - Device lifecycle states — devices carry a lifecycle of planned / active / retired / ignored. Only active devices are monitored; the rest render as paused in Monitoring and show a lifecycle badge in device details.
- Flapping detection — devices whose status changes 4+ times within an hour get a "flapping" badge in the Monitoring table, and a new "Device is flapping" alert rule trigger fires through the normal notification channels with per-rule cooldown.
- Notification delivery history — every alert notification attempt is recorded (rule, target, sent/failed, provider error summary) and shown in Admin → Alerts → Delivery history. Records are pruned after 30 days. Migration
0039_notification_deliveries. - Generic webhook notification method — Admin → Notifications now offers "Generic webhook": NetMap POSTs
{"title": "NetMap", "message": …}as JSON to any HTTP(S) endpoint, with an optional bearer token. Respects the private-target egress blocking setting. - IPAM next-available-IP — the Reserve IP dialog can fill in the next free address of the selected subnet with one click, skipping used IPs, the gateway, and the DHCP pool.
- IP reservation expiry dates — new reservations default to an expiry 90 days from today, expired reservations are flagged in the reservations table, and a "Clear expired" action removes them in bulk. Migration
0040_ip_reservation_expiry. - Saved security searches — the Security workspace can save the current filter set under a name and re-apply or delete it from a dropdown. Saved per user. Migration
0041_saved_security_searches. - What's new popup — after login, authenticated users see a once-per-installed-version popup summarising the changelog for the version they're running. It does not prompt when a newer tag is merely available; Admin → Version can reopen it manually. GitHub release notes for
v*tags are generated from the sameCHANGELOG.mdin CI. - Managed custom device types — Admin → Devices & Icons can add reusable custom device types, edit/rename them, assign a default Tabler icon, and remove unused custom types. Device forms, Inventory bulk actions, Topology, and Overview all consume the same managed type list. Migration
0042_device_types. - Interactive monitoring summary cards — the Monitored/Online/Offline cards in Monitoring now click to apply the matching status filter (click again to clear).
- GitHub Actions security scanning — a new report-only
security-scan.ymlworkflow runs Semgrep SAST pluspip-auditandnpm auditon pushes, pull requests, and a weekly schedule. All jobs are non-blocking until the baseline is triaged. - Instant Monitoring re-entry — the Monitoring workspace keeps an in-memory stale-while-revalidate snapshot of the fleet summary, device table, and service checks. Returning to Monitoring renders the last known data immediately, then refreshes with a lightweight delta request when fresh or a full refresh when stale.
Changed
- Sidebar collapse control — the collapse/expand button now stays in the bottom utility area above a subtle separator in both sidebar states, and the collapsed Inventory badge now sits at the icon's top-right corner instead of pushing it off-centre or overlapping it.
- HTTP/HTTPS monitoring scope clarified — the current service-check groundwork is no longer described as the finished uptime-monitoring workflow; the dedicated HTTP/HTTPS monitoring method with per-check targeting, response timing, and alert integration remains planned.
- CI and bundle analysis cleanup — GitHub workflows now use current major action versions for the Node 24 runner runtime, and normal production frontend builds skip the bundle visualizer unless explicitly run in analyze mode.
- Browser tab titles now show only the current screen — authenticated pages use their page name without the
NetMap —prefix, and login/setup/reset/loading states now show their own tab title instead of inheriting Overview. - What's New release notes now render inline Markdown — changelog bullets in the popup preserve formatting such as links, inline code, emphasis, strikethrough, and bold text while sanitising rendered HTML before display.
- What's New actions — the release-notes action now sits to the left of the close action in the popup footer, "Got it" is the primary action, and the Admin → Version "What's new" control now matches the primary admin action buttons.
- Overview favourites cache — favourite monitoring rows render from a per-user local snapshot while Overview refreshes live monitoring data in the background, avoiding the empty/loading lag on page entry.
- Overview card surfaces — the Overview summary cards and panels now use the same restrained linear-gradient surface treatment as the refreshed admin cards for a more consistent dashboard feel.
- Admin stat card vibrancy — the Admin → System cards now use per-card accent gradients, stronger icon tints, and matching hover glow so they feel closer to the Overview cards instead of washed out.
- OIDC admin form polish — the SSO checkboxes in Admin → Security now match the System settings layout, with option text beside the checkbox, compact helper text underneath, and clearer spacing before Login & Audit History.
- Confirmation toasts — Admin success messages such as "Settings saved", plus Profile and Export confirmations, now use the toast stack instead of full-width success bars. Toast notifications are larger and stay visible longer so saves are harder to miss.
- Full Tabler icon library for device types — the device-type icon picker now exposes the installed Tabler outline library in addition to the curated NetMap icon set. The large Tabler metadata files are emitted as lazy JSON assets so the initial app bundle stays small.
- Unified table row hover across the app — VLANs, Inventory, Monitoring, IPAM, Security, Overview device lists, audit logs, admin tables, the icon manager, and the topology entity list now share one subtle hover treatment (new
--nm-row-hoverdesign token) with the VLAN table's teal left-edge accent in both themes, replacing a patchwork of per-table hover colours. - Tools action buttons calmed down — Lookup, Ping, Traceroute and the other tool submit buttons use the soft accent treatment (tinted background, teal text) instead of a solid bright block, which was overpowering in dark mode.
- Unified near-duplicate UI colours onto the design-token palette — 485 hard-coded colour values that were visually near-identical to an existing theme token now use the token, keeping light and dark mode consistent as the palette evolves. The changes are imperceptible by design and were verified against light/dark screenshot baselines of every workspace.
Fixed
- Monitoring drilldown popup surface — the device drilldown modal now uses the standard app surface colours again instead of the stronger blue-toned background.
- IPAM subnet address popup surface — the subnet detail modal that shows the grid/table of IP addresses now uses the lifted neutral surface family from the approved Monitoring drilldown palette, avoiding the overly dark inherited modal background.
- Monitoring/IPAM table formatting regression — shared numeric-stability styling no longer turns Monitoring and IPAM table cells into pill-shaped inline elements, restoring normal table layout and dashboard card values.
- Monitoring status-dot motion — Monitoring and port-check status dots now use a slower, softer pulse so live state remains visible without drawing as much attention.
- Device saves now confirm completion — saving device edits now shows a success toast with the device name, so the details panel no longer feels like the Save action did nothing.
- Custom device type edits now use a PUT update route — Admin → Devices & Icons no longer hits a 405 when saving a renamed custom type, and the row closes after the save succeeds.
- Admin panel spacing and confirmation dialogs — admin cards keep the subtle linear-gradient accent treatment, success banners have more even spacing from surrounding content, Inventory tables align with the page rail, delivery history has more breathing room below alert rules, the topology grid's top-left corner is square, and destructive confirmation icons sit in the modal title area.
- IP reservation expiry default setting — Admin → System can now toggle whether new IPAM reservations prefill a +90 day expiry. Users can still clear the expiry field on a reservation to remove it entirely.
- Admin settings polish — the System settings helper text now renders as compact hint text below each related option, and the System stat cards now follow the same card shape and hover feel as the dashboard/monitoring stat cards.
- Inventory row hover works again — hover now animates the row itself with the shared teal edge treatment in light and dark mode, so zebra stripes and active-row backgrounds no longer hide the mouseover state.
- Dark mode readability fixes across the app — the NetMap wordmark on the login screen, the sidebar network-changes badge, the sidebar logo hover, primary buttons ("+ Device", "Ports", "+ Add subnet"), and toolbar dropdowns are all readable in dark mode again; plain secondary buttons (e.g. IPAM "Next free"/"Edit") use the raised-blue treatment instead of near-black; Locations cards use the standard panel surface instead of an extra-dark background; and the monitoring device popup shows its status colour bar in dark mode, matching light mode.
- Saving a security search now uses a styled in-app dialog with a name field and validation instead of the browser's native prompt window.
- Custom roles appear in Admin → Users immediately — the role dropdowns for existing users and the add-user form now list custom groups without first visiting the Groups tab.
- Admin tabs load faster and independently — each Admin tab (System, Users, Groups, SNMP Profiles, Notifications, Alerts, Automation, Security) now fetches only its own data when opened, and a slow or failing load in one tab no longer affects the others. The Automation tab also stopped fetching an unused sites list on every visit.
- Refreshing the browser on the IPAM page no longer bounces to Overview — the router now restores every route, including
/ipam. - Expired sessions mid-action recover transparently — if the access token expires while the app is open (e.g. after laptop sleep), the next API call refreshes the session and retries once instead of surfacing a 401 error.
- Background token refresh no longer flashes the loading screen — the hourly session refresh (and any transparent 401 recovery) keeps the current page rendered instead of re-running the app bootstrap.
- Modals are keyboard-trapped and restore focus — Tab cycles within any open modal, background scrolling is locked, and focus returns to the triggering control on close.
- Browser tab titles now reflect the current page (e.g. "NetMap — Monitoring").
- Scheduled discovery IP conflicts are review-only — when a scheduled scan finds a MAC-matched device at an IP that already belongs to a different inventory device, the move is no longer misattributed as a field change on the occupying device. It now creates an
ip_changeobservation against the MAC-matched device for manual review, and the IP is never auto-applied onto an occupied address. - Topology link form endpoint pickers now render above the modal scroll layer with an opaque dropdown surface, preventing the source/target menu from being clipped, hidden, or see-through while creating or editing links.
- Topology links dropdown now uses fixed source/target/type columns so long link labels no longer shift row spacing.
- Device pause controls now update Topology/Inventory state consistently, show paused devices with neutral gray styling instead of red, and expose Paused in the Inventory status filter.
- Monitoring drilldown pause control now lets writable users pause/resume an individual active device from the Monitoring popup, while lifecycle-paused devices explain why they cannot be resumed there.
- IPAM next-free reservation is now visible from subnet rows and the subnet detail modal, not only inside the generic reserve dialog.
- IPAM reserve and next-free actions now use the secondary button treatment from the unified UI styles; the subnet popup keeps "Reserve next IP" in the top bar beside close.
- Pause controls in device details, Inventory details, and the Monitoring popup now use the shared secondary button treatment from the design-system preview.
- Dark-mode secondary buttons now use the same raised blue family as the Monitoring popup header, so pause/resume controls remain visible before hover without clashing with the modal surface.
- Device detail status dots now strobe subtly with a status-coloured glow so the selected device state feels live and interactive.
- Monitoring status dots now use a stronger status-coloured strobe in the device table and popup header, while respecting reduced-motion preferences.
- Monitoring offline alert spacing now has more even top/bottom padding so the alert bar feels balanced.
- Monitoring summary cards no longer show the active filter ring on the default Monitored card; only explicit status filters stay highlighted.
- Paused device status now uses a non-pulsing neutral gray treatment across Monitoring, Inventory/detail badges, topbar paused state, and topology labels.
- Scheduled discovery disappeared-host alerts now require three consecutive missed scheduled scans before opening a network-change observation, reducing noise from devices that only intermittently respond.