Commit Graph
17 Commits
Author SHA1 Message Date
bobbanandClaude Sonnet 5 d714a87754 Add a "Sync from Tailscale" action to IP Addresses (IPAM)
IPAM was entirely manual — Tailscale device IPs never showed up there
even though the Tailscale integration already lists them. Add an
explicit sync action (matching this app's existing pattern of
user-triggered syncs rather than silent background polling).

- New source column on ipam_entries (null = manual, "tailscale" =
  auto-synced) so a re-sync only ever touches rows it created itself —
  a manually-entered IP that happens to collide with a tailnet address
  is left untouched and reported back as skipped, never overwritten.
- POST /api/ipam/sync-tailscale pulls every enabled Tailscale
  integration's device list, upserting by primary IP (label, OS in
  notes, vendor "Tailscale"); one unreachable Tailscale integration
  doesn't block others.
- New "Sync from Tailscale" button on the IP Addresses page, with a
  small "synced" badge marking which rows came from it.

Also fixed a longstanding TODO found in the same file: the "DNS
records" column always showed "-" because matchingDnsRecords was
hardcoded to an empty array from before the DNS module existed. It
now does the same content-based reverse lookup against the DNS
module's record cache used elsewhere in the app.

Verified end-to-end by running the real server with Tailscale's fetch
call intercepted at the process level (its adapter hardcodes
api.tailscale.com with no configurable URL, so it can't be pointed at
a mock server the way Proxmox/Synology can): confirmed add, the
manual-entry skip/never-overwrite behavior, idempotent re-sync
(add -> update), and the DNS-matching fix, all against the real
route and adapter code.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 23:16:17 +02:00
bobbanandClaude Sonnet 5 f92f8de96e Add a Date & Time setting and fix inconsistent date formats app-wide
Different tables used different date formats: Servers & Tasks used a
fixed "YYYY-MM-DD HH:mm:ss" (24h), while Audit Log, DNS, Integrations
(Tailscale/Semaphore), and Users called plain .toLocaleString() with
no options, which renders using the browser's own locale — different
per browser/OS, and inconsistent with the other pages' fixed format.

- New Settings -> Date & Time page: pick date order (YYYY-MM-DD,
  DD/MM/YYYY, MM/DD/YYYY) and 12h vs 24h clock, with a live preview.
- utils/date.ts's formatDateTime() now reads these settings instead of
  being hardcoded to sv-SE/24h; the setting is fetched once at app
  startup (alongside /api/me) via a new non-secret GET
  /api/settings/display (any signed-in user, same rationale as the
  badge-color endpoints) and applied immediately on save too, without
  needing a page reload.
- Switched every remaining raw new Date(...).toLocaleString() call
  (Audit Log, DNS zone sync time, Tailscale/Semaphore last-seen,
  Users' last login) over to the shared formatter, so every table now
  renders dates identically.

Verified the formatter's date-order x 12h logic against all six
combinations plus the midnight/noon 12h edge cases, and the settings
endpoints end-to-end (defaults, partial updates, validation
rejection, audit logging) against the real dev server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 22:17:06 +02:00
bobbanandClaude Sonnet 5 ad6783b6a1 Extend badge color settings to cover integration types too
Settings → DNS Badges only let you customize DNS provider badge
colors. Expand it into a general Badges page with a second section
for the six integration types (Tailscale, Proxmox, Synology,
Semaphore, Gitea, Dockhand), applied to the type badge in the Manage
integrations table.

- New integrationColors key on AppSettings, stored/merged the same way
  as providerColors via the existing settingsStore.
- New GET /api/settings/integration-colors — non-secret, any signed-in
  user, mirroring /provider-colors — so the badge color can be read
  without needing admin access to the full settings payload.
- Renamed DnsBadgeSettings.tsx -> BadgeSettings.tsx (route
  /settings/dns-badges -> /settings/badges, sub-nav label "DNS
  Badges" -> "Badges") with both color sections saved together.

Verified end-to-end against the real dev server: PUT persists
integration colors independently of provider colors, the public
integration-colors endpoint reflects updates immediately, and the
change is audit-logged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 21:28:26 +02:00
bobbanandClaude Sonnet 5 de9b6a2d6a Add start/restart/stop buttons to Proxmox-linked servers' detail page
The Proxmox start/stop/restart routes already existed (used by the
Integrations page's guest table) but weren't reachable from a server's
own detail page, even when that server was linked to a Proxmox guest.

Reuses the existing POST /api/integrations/:id/proxmox/nodes/:node/
:type/:vmid/{start,stop,restart} routes and the operator+ role gate
already enforced there — no server-side changes needed. Buttons only
render for hardware.source === "proxmox", mirroring the Integrations
page's running/stopped button-set logic, with the same confirm-before-
stop prompt for the non-reversible action.

Verified end-to-end against the real dev server with a mock Proxmox
HTTPS server: linked a server to a mock guest, confirmed the detail
endpoint's live status, then triggered restart/stop/start and
confirmed the mock actually received each action and every call was
audit-logged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 20:46:35 +02:00
bobbanandClaude Sonnet 5 f5d3c25c89 Add editing existing integrations, so an expired secret can be rotated
Manage integrations only supported add/toggle/delete — fixing an
expired API token meant deleting and recreating the whole integration.

- New GET /api/integrations/:id/config returns only the non-secret
  config fields (never the decrypted secret) so an edit form can
  pre-fill URL/tailnet/etc. fields.
- New POST /api/integrations/:id/test merges the stored, decrypted
  config with any freshly-typed overrides and pings the real adapter —
  lets "Test connection" work during an edit without ever sending the
  current secret back to the browser.
- New IntegrationEditForm component: secret fields render blank with a
  "leave blank to keep the current value" placeholder; submitting only
  sends the fields that were actually filled in, so a name/URL edit
  can't accidentally wipe a secret and a secret rotation can't touch
  anything else. Reuses the existing PATCH /:id route, which already
  merged partial config updates correctly.

Verified end-to-end against the real dev server: confirmed via direct
DB decryption that a non-secret-only edit leaves the stored secret
byte-for-byte unchanged, and that a secret-only edit rotates it without
touching other config; the test route was confirmed to make a real
network call (got a genuine "API token invalid" from Tailscale's API
against a fake key).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 13:12:17 +02:00
bobbanandClaude Sonnet 5 b9409d3095 Add server hardware/network detail view with Proxmox sync and agent reporting
Servers & Tasks only tracked scheduled tasks — there was no overview of
the servers themselves and no way to see CPU/RAM/disk/IP info. Add a
clickable server overview (visible to every role, not just admins) that
opens a per-server detail page.

- servers table gains an agent-reported hardware/network snapshot
  (IPs, CPU model/cores/load, memory, disks) and an optional link to a
  Proxmox VM/LXC (integration + node + guest type + vmid).
- Proxmox adapter gains getGuestDetail(): live cores/memory/disk from
  /config, live cpu/mem/uptime from /status/current, and IPs (LXC net
  config directly, QEMU via a best-effort guest-agent call that degrades
  gracefully when the agent isn't installed).
- New GET /api/servers/:id/detail combines whichever hardware source
  applies (live Proxmox vs. last agent report) with a DNS reverse-lookup
  against the DNS module's own record cache, so matching hostnames show
  up next to each IP. New PATCH /api/servers/:id manages the Proxmox
  link.
- agent/linux/report-tasks.sh now also collects and reports IPs,
  CPU/memory/disk info on every check-in (load-average-based CPU number,
  not instantaneous, to keep the agent a cheap oneshot).
- Extracted the per-server task table into a shared ServerTaskTable
  component so the all-servers view and the new detail page render
  tasks identically.

Verified server-side end-to-end against the real dev server (agent
report -> detail endpoint -> DNS match) and the Proxmox adapter against
a mock HTTPS server covering LXC/QEMU config parsing and the
guest-agent-unavailable fallback.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 13:02:50 +02:00
bobbanandClaude Sonnet 5 3255314402 Build the Settings module: notification channels, event toggles, DNS badge colors
The Settings page was a "coming soon" placeholder. Port Sloth Manager's
settings feature set: Gotify/ntfy/SMTP/webhook notification channels
(each with its own test-send button), per-event toggles (DNS record
added/updated/deleted, a daily secret-expiry digest with configurable
time/timezone), and per-provider DNS badge color customization.

Settings persist in the existing `settings` key/value table via a new
settingsStore service; a notify service fans a message out to every
enabled channel. DNS record add/update/delete now fire notifications,
and a node-schedule job re-arms itself whenever the notification
settings change. Removed the now-superseded GOTIFY_URL/GOTIFY_TOKEN
env vars in favor of in-app configuration.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 12:14:05 +02:00
bobbanandClaude Sonnet 5 e064b1caf7 Update README: add repository link, mark all integrations as verified
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 01:22:19 +02:00
bobbanandClaude Sonnet 5 afc920e96e Update README: all planned modules and integrations are now built
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 00:35:50 +02:00
bobbanandClaude Sonnet 5 ae39f18755 Update README: Proxmox integration is now built
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 00:24:59 +02:00
bobbanandClaude Sonnet 5 257ec3ec0a Update README: Semaphore integration is now built
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 00:15:01 +02:00
bobbanandClaude Sonnet 5 1504c19bbd Update README: Dockhand integration is now built
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 00:04:50 +02:00
bobbanandClaude Sonnet 5 f54709c7a8 Update README: Gitea integration is now built
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 23:56:07 +02:00
bobbanandClaude Sonnet 5 069225c656 Update README: Tailscale integration is now built
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 23:31:35 +02:00
bobbanandClaude Sonnet 5 3bb0c767b9 Update README: Servers & Tasks module is now built
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 23:17:13 +02:00
bobbanandClaude Sonnet 5 ac3feb935d Update README: DNS module is now built
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 23:00:47 +02:00
bobbanandClaude Sonnet 5 89919fdbff Add README with setup instructions and current build status
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 21:57:38 +02:00