Displays when the per-customer token was last (re-)issued and its
computed expiry (365 days from renewal) on the Auto-Updates card, so it's
visible at a glance without checking the database.
The per-customer Auto-Updates card only showed the token input when no
token was registered yet, so there was no way to replace one once set
(e.g. rotating it manually). Adds a "Change token" link that reveals the
same input/save flow at any time.
Lets the MSP admin control NetBird's own "Settings > Clients > Automatic
Updates" feature (client/peer auto-update, v0.61.0+) for every customer from
one place, instead of logging into each customer's dashboard individually.
- New deployments automatically capture a Personal Access Token during the
existing /api/setup bootstrap call (create_pat=true), requiring
NB_SETUP_PAT_ENABLED=true on the management container (now set by default
in the compose template). Token is encrypted at rest per customer.
- Existing customers (deployed before this existed) can have a token pasted
in manually from their own dashboard — verified before being stored.
- Settings > Docker Images: master default (version + force-update toggle)
plus "Apply to All Customers" which pushes it to everyone with a token.
- Customer detail page: shows the customer's live current setting (read
from their NetBird API, not cached) with per-customer override or
"sync from default".
- New app/services/netbird_client_update_service.py wraps the customer's
NetBird Management API (GET/PUT /api/accounts) for this.
Customer container status checks looked up containers by an exact expected
name. When a docker compose recreate got interrupted (e.g. a hung command
previously killed the whole update-all batch on timeout), Compose could leave
the old container renamed with a random hash prefix instead of removed. The
exact-name lookup then found nothing, returned None, and that silently
counted as "up to date" (green "Aktuell") instead of surfacing as unknown —
affecting 5 customers on the appliance whose containers were actually still
running under orphaned names.
- _run_cmd no longer raises on subprocess timeout, so one stuck customer
can't abort the rest of a batch update
- repair_container_naming() self-heals orphaned hash-renamed containers by
renaming them back before every status check and before recreate
- update-all loop now catches per-customer exceptions instead of aborting
- status responses expose "unknown" separately from "needs_update" so the UI
shows a distinct grey badge instead of a false-positive green one
- new settings: automatic daily update check (on/off + time), with an
independent toggle for whether it also auto-recreates customer containers
The update endpoint ran the entire git pull + docker build (up to 10 min)
synchronously inside the request handler, blocking the whole server for
everyone while it ran. Separately, the frontend spinner was only hidden on
error, never on success, so it spun forever even when the update worked.
- Run the update in a background thread; the request returns immediately
- Add GET /settings/update/status for progress polling (backup/pull/build/restart)
- Frontend polls status, then waits for the app to come back after the
container restart, and shows a clear done/timeout message instead of an
endless spinner
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Add a confirmation modal when clicking Redeploy that lets the user choose:
- Keep Data: containers are recreated without wiping the instance directory.
NetBird database, peer configs, and encryption keys are preserved.
- Fresh Deploy: full undeploy (removes all data) then redeploy from scratch.
Backend changes:
- POST /customers/{id}/deploy accepts keep_data query param (default false)
- When keep_data=true, undeploy_customer is skipped entirely
- deploy_customer now reuses existing npm_proxy_id/stream_id when the
deployment record is still present (avoids duplicate NPM proxy entries)
- DNS record creation is skipped on keep_data redeploy (already exists)
Frontend changes:
- customerAction('deploy') opens the redeploy modal instead of calling API
- showRedeployModal(id) shows the two-option confirmation card dialog
- confirmRedeploy(keepData) calls the API with the correct parameter
- i18n keys added in en.json and de.json
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Dashboard: update badge (orange) injected lazily into customer Status cell
after table renders via GET /monitoring/customers/local-update-status
(local-only Docker inspect, no Hub call on every page load)
- Customer detail Deployment tab: "Update Images" button with spinner,
shows success/error inline without page reload
- Monitoring Update All: now synchronous + sequential (one customer at a
time), shows live spinner + per-customer results table on completion
- Settings > Docker Images: "Pull from Docker Hub" button with spinner
and inline status message
- /monitoring/customers/local-update-status: new lightweight endpoint
(no network, pure local Docker inspect)
- /monitoring/customers/update-all: removed BackgroundTasks, now awaits
each customer sequentially and returns detailed per-customer results
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- New image_service.py: Docker Hub digest check (no pull), local digest/ID
comparison, pull_all_images, per-customer container image status, and
update_customer_containers (docker compose up -d, data-safe)
- Monitoring endpoints: GET /images/check (hub vs local + per-customer
needs_update), POST /images/pull (background), POST /customers/update-all
- Deployment endpoint: POST /{id}/update-images (single-customer update)
- Monitoring page: "NetBird Container Updates" card with Check / Pull / Update
All buttons; image status table and per-customer update table with inline
update buttons
- i18n: added keys in en.json and de.json
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Backend: add admin-only guard + role validation to PUT /users/{id}
- Backend: prevent admins from changing their own role
- Frontend: role toggle button (person-check / person-dash) per user row
- Frontend: admin badge green, viewer badge secondary, ldap badge blue
- i18n: add makeAdmin / makeViewer translations (de + en)
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Settings page: 3 new tabs (Windows DNS, LDAP / AD, Updates)
- Windows DNS tab: enable toggle, server/zone/username/password/record-IP,
save + test connection button
- LDAP tab: enable toggle, server/port/SSL/bind-DN/password/base-DN/
user-filter/group-DN, save + test connection button
- Updates tab: current + latest version info card with update-available
badge, one-click update button (git pull + rebuild), git repo/branch/
token settings form
- Azure AD tab: added Allowed Group Object ID field
- app.js: settings-dns-form, settings-ldap-form, settings-git-form
submit handlers; testDnsConnection(), testLdapConnection(),
loadVersionInfo(), triggerUpdate() functions; loadSettings() extended
for all new fields
- en.json: all new translation keys
- de.json: complete German translation (was mostly empty before)
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Settings > NPM Integration now allows choosing between per-customer
Let's Encrypt certificates (default) or a shared wildcard certificate
already uploaded in NPM. Includes backend, frontend UI, and i18n support.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Global MFA toggle in Security settings, QR code setup on first login,
6-digit TOTP verification on subsequent logins. Azure AD users exempt.
Admins can reset user MFA. TOTP secrets encrypted at rest with Fernet.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Multi-language support (EN/DE) with i18n engine and language files
- Configurable branding (name, subtitle, logo) in Settings
- Global default language and per-user language preference
- User management router with CRUD endpoints
- Customer status sync on start/stop/restart
- Health check fixes: derive status from container state, remove broken wget healthcheck
- Caddy reverse proxy and dashboard env templates for customer stacks
- Updated README with real hardware specs, prerequisites, and new features
- Removed .claude settings (JWT tokens) and build artifacts from tracking
- Updated .gitignore for .claude/ and Windows artifacts
Co-Authored-By: Claude Opus 4.6 <[email protected]>