bobbanandClaude Sonnet 5 da34be08d5 Fix Tailscale online/exit-node detection against real API data
Found while verifying against the user's real tailnet (25 devices): the
Tailscale device object has no "online" or "isExitNode" field at all — this
was inherited from Sloth Manager's original adapter, which apparently never
had this checked against live data either. With the old mapping, every
device showed online:null and isExitNode was always false regardless of
reality.

Fixed by deriving both from fields that actually exist:
- online <- connectedToControl (whether the device currently has an active
  session with Tailscale's control plane)
- isExitNode <- enabledRoutes containing both 0.0.0.0/0 and ::/0 (a device
  can *advertise* exit-node routes without them being approved; checking
  enabledRoutes instead of advertisedRoutes reflects whether it's actually
  acting as one right now)

Both fields come back from the list endpoint via `?fields=all`, so this
adds no extra requests.

Verified against the real tailnet: 25 devices, 24 online / 1 offline (a
phone last seen 9 days ago — correct), and the one device actually
configured as an exit node identified correctly. This is the last of the
five previously-unverified integrations now confirmed against real
infrastructure; combined with the earlier Synology (HTTP vs HTTPS) and
Proxmox (async task timing) findings, every integration has now had at
least one real bug shaken out by testing against the user's actual homelab
rather than mocks alone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 01:09:27 +02:00
2026-09-14 21:57:13 +02:00

Homelab Manager

A single dashboard for a homelab: Proxmox, Synology DSM, Semaphore, Tailscale, Gitea, and Dockhand/Docker status and basic actions, plus DNS record management, an IP address inventory (IPAM), and a secret-expiry tracker (ported from Sloth Manager) and scheduled-task tracking across Debian/Raspbian hosts (ported from Schedule Task Manager). Looks and feels like a Tabler admin dashboard. Sign-in is delegated to Authentik (OIDC), with local admin/operator/viewer roles.

Status

All modules from the original plan are built:

  • Monorepo scaffold, Tabler-themed app shell/navigation
  • Authentik OIDC login, roles (first user to sign in becomes admin), audit log
  • Secrets — expiry tracking for API tokens/certs/passwords
  • IP Addresses (IPAM) — inventory of IPs across vendors/locations
  • DNS — zone/record management across Cloudflare, Loopia, Pi-hole, Azure DNS, cPanel, and Technitium; providers are configured in-app (not via env vars) and their credentials are encrypted at rest
  • Servers & Tasks — cron/systemd tracking across Debian/Raspbian servers via a lightweight push agent (agent/linux/), plus manual entries for things an agent can't see (Docker jobs, backups)
  • Integrations → Tailscale — device list with online/authorized status, and authorize/deauthorize/remove actions; a live device-count widget.
  • Integrations → Gitea — repo list with each repo's last CI run status, and re-running just the failed jobs in a run; a live repo-count widget (with a failing-build warning).
  • Integrations → Dockhand — container status across every Docker host Dockhand manages (one credential covers all of them), with start/stop/restart actions; a live running/total widget.
  • Integrations → Semaphore — Ansible run status per template across every project, with a "Run" action to trigger a template; a live template-count widget (with a last-failed warning).
  • Integrations → Proxmox — VM/LXC status across every node in the cluster, with start/stop/restart actions; a live running/total widget. Supports self-signed certificates (common in homelab Proxmox setups).
  • Integrations → Synology — volume and disk health (read-only by design). Supports self-signed certificates.

All six integrations follow the same config-in-UI + encrypted-credentials pattern, added through Integrations → Manage integrations.

What's been verified for real vs. what still needs your network: Authentik login and Gitea were both tested against the user's actual live services. Tailscale, Dockhand, Semaphore, Proxmox, and Synology were built against each service's real published API spec/source (not guesswork) and verified with scripted HTTP tests against a bogus/unreachable config, since those instances are LAN-only and not reachable from where this was built — their route wiring, validation, and role gating are confirmed correct, but real data and the write actions (start/stop/restart, trigger-a-run) haven't been exercised against the user's actual homelab yet. Worth going through each one after deploying, per integration.

Requirements

  • Node.js 20+
  • An Authentik instance reachable from wherever this app runs

1. Set up an Authentik application

  1. Create an OAuth2/OpenID Provider:
    • Redirect URI: <APP_BASE_URL>/auth/callback
    • Scopes: openid, email, profile
  2. Create an Application using that provider, and assign the users/groups who should be able to sign in — Authentik controls who can authenticate; the app's own admin/operator/viewer roles control what they can do once in.
  3. Copy the provider's issuer URL, client ID, and client secret into .env.

2. Local development

cp .env.example .env   # fill in AUTHENTIK_*, SESSION_SECRET, CREDENTIALS_ENCRYPTION_KEY
npm install
npm run dev:server   # http://localhost:3000 (API)
npm run dev:web      # http://localhost:5173 (Vite dev server, proxies /api and /auth to :3000)

Visit http://localhost:5173 during development. Database migrations run automatically on server start. SQLite data lands in ./data (gitignored).

Generate SESSION_SECRET and CREDENTIALS_ENCRYPTION_KEY with:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

3. Run with Docker

cp .env.example .env
# edit .env
docker compose -f docker-compose.dev.yml up -d --build   # build locally
# or, once an image is published to your registry:
docker compose up -d

The app listens on HOST_PORT (default 3000); SQLite data persists in ./data on the host.

S
Description
No description provided
Readme
1,009 KiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 96.5%
PowerShell 1.9%
Shell 1.3%