ArchNest paid SaaS line (AWS) — forked from open-source v1 (dev_archnest v1.0)
Find a file
Samuel James 63adccb1c7
Show saved indicator for secret fields instead of appearing deleted (#18)
* Add editable display-name field to generic integrations

Lets users set a custom name for Proxmox, Docker, AWS, Remote Desktop,
Netbird, Cloudflare, Uptime Kuma, and Weather integrations, separate
from the host/IP field, mirroring the SSH host rename pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4

* Surface the new-integration name field as a labeled input

The name field for new generic integrations was a faint header input
with only placeholder text, easy to miss. Move it into the form grid
as a proper labeled "Name" field next to the other connection fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kF4hZWEkRCPPvCZTeXxn4

* Add file upload for SSH private key and certificate fields

Lets users pick a key file from disk (e.g. ~/.ssh) instead of pasting
its contents into the Private Key / OPKSSH Certificate fields.

* Fix SSH private key paste corrupting multi-line PEM format

Private Key and Certificate fields were single-line <input> elements,
which strip newlines on paste and corrupt PEM-formatted keys (causing
'Unsupported key format' errors). Render them as multi-line textareas
instead so pasted keys keep their line breaks.

* Show saved indicator for secret fields instead of appearing blank/deleted

GET /api/integrations never returns decrypted secret values (by design),
so after navigating away and back, secret/key fields rendered empty -
looking exactly like the saved key had been deleted, even though it was
still intact and encrypted in the database. Expose which secret keys
exist (names only, never values) via secretKeys, and use it to label
fields as "saved" with an appropriate placeholder instead of blank.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-20 08:53:56 -04:00
.github/workflows Production deploy: nginx /api proxy, native-module toolchain, hardened CI 2026-06-19 14:22:08 -06:00
.kiro update 2026-06-18 08:14:00 -04:00
assets Restore Resource Distribution card, remove Resource Utilization, apply blank KPI bg to status row 2026-06-18 17:26:39 +00:00
backend Show saved indicator for secret fields instead of appearing deleted (#18) 2026-06-20 08:53:56 -04:00
pics network kip 2026-06-18 12:34:31 -04:00
public Fix favicon, dark select dropdowns, add brand bookmark icons and Help page 2026-06-19 21:13:32 +00:00
src Show saved indicator for secret fields instead of appearing deleted (#18) 2026-06-20 08:53:56 -04:00
.dockerignore Add Docker deployment and GitHub Actions workflow for racknerd1 2026-06-18 14:18:00 +00:00
.env.example Update docs: mark feature work complete, document deploy setup as the only remaining task 2026-06-19 16:41:32 +00:00
.gitignore Add backend skeleton: Fastify + SQLite API with auth and integrations 2026-06-18 19:04:48 +00:00
archnest-blueprint.md pics 2026-06-11 19:26:56 -05:00
design-decisions.md Add backend skeleton: Fastify + SQLite API with auth and integrations 2026-06-18 19:04:48 +00:00
docker-compose.yml Wire guacd sidecar into docker-compose for Remote Desktop deployment 2026-06-19 16:03:40 +00:00
Dockerfile Add Docker deployment and GitHub Actions workflow for racknerd1 2026-06-18 14:18:00 +00:00
eslint.config.js update 2026-06-18 08:14:00 -04:00
glance.md update 2026-06-18 08:14:00 -04:00
HANDOFF.md Update docs: mark feature work complete, document deploy setup as the only remaining task 2026-06-19 16:41:32 +00:00
index.html Fix favicon, dark select dropdowns, add brand bookmark icons and Help page 2026-06-19 21:13:32 +00:00
nginx.conf Production deploy: nginx /api proxy, native-module toolchain, hardened CI 2026-06-19 14:22:08 -06:00
package-lock.json Phase 5: RDP/VNC/Telnet remote desktop via guacamole-lite + guacd 2026-06-19 15:25:10 +00:00
package.json Phase 5: RDP/VNC/Telnet remote desktop via guacamole-lite + guacd 2026-06-19 15:25:10 +00:00
README.md Update docs: mark feature work complete, document deploy setup as the only remaining task 2026-06-19 16:41:32 +00:00
TERMIX_MIGRATION.md Update docs: mark feature work complete, document deploy setup as the only remaining task 2026-06-19 16:41:32 +00:00
tsconfig.app.json update 2026-06-18 08:14:00 -04:00
tsconfig.json update 2026-06-18 08:14:00 -04:00
tsconfig.node.json update 2026-06-18 08:14:00 -04:00
vite.config.ts Add Phase 1a: core SSH terminal (Termix migration) 2026-06-19 10:52:04 +00:00

ArchNest

A self-hosted ops dashboard — infrastructure monitoring, a bookmark hub for your homelab/cloud links, an embedded terminal, and system settings, all in one place. Real backend, real integrations, no mock data.

Frontend: React 19 + TypeScript + Vite, styled with Tailwind CSS v4, charts via Recharts, icons via Lucide React. Backend: Fastify + TypeScript + SQLite (better-sqlite3), JWT auth, AES-256-GCM encrypted integration secrets.

For a full handoff/status writeup (what's done, what's not, how to resume), see HANDOFF.md.

Pages

Page Route Status
Glance / Done — real backend data (system status, resource overview, alerts, network traffic)
Infrastructure /infrastructure Done — resource distribution, node status grid, cost/trend breakdown, all from real integration data. "Network" sub-tab planned as a future addition.
BookNest /booknest Done — categorized bookmark hub wired to the real bookmarks API
Terminal /terminal Pending / on hold — will be based on a fork of the (archived) Termix project; user has the fork and intends to hand this off to another AI session to integrate. Do not start this without explicit instruction.
Settings /settings Done — Profile (real user identity + avatar, editable via API), Appearance, Integrations (8 real adapters), Notifications, Data & Backup, About

See archnest-blueprint.md for the original per-page design spec and design-decisions.md for the visual/UX conventions and lessons learned while building each page — read that file before making layout changes, it documents why things are built the way they are (hero banner layering, card blend techniques, icon library gotchas, etc.).

Development

Frontend:

npm install
npm run dev

Backend:

cd backend
npm install
ARCHNEST_SECRET_KEY=$(openssl rand -hex 32) ARCHNEST_JWT_SECRET=$(openssl rand -hex 32) npm run dev

Both ARCHNEST_SECRET_KEY (encrypts integration secrets at rest) and ARCHNEST_JWT_SECRET (signs auth tokens) are required env vars with no defaults — the server will refuse to start without them. ARCHNEST_DB_PATH optionally overrides the SQLite file location (defaults to a local path under backend/). PORT overrides the listen port (default 4000-range, check server.ts).

Type-check both before committing:

npx tsc --noEmit          # from repo root, frontend
cd backend && npx tsc --noEmit   # backend

Vite/the browser surface some runtime errors (e.g. missing icon exports) that the type-checker won't catch, so also smoke-test pages in a browser.

Tech Stack

Frontend

  • React 19 + Vite + TypeScript
  • React Router for routing
  • Tailwind CSS v4
  • Recharts (donuts, line/area charts)
  • Lucide React (icons)

Backend

  • Fastify 5 + TypeScript, tsx for dev, tsc -b for build
  • better-sqlite3 for storage
  • @fastify/jwt for auth tokens, bcryptjs for password hashing
  • zod for request validation
  • AES-256-GCM (Node crypto) for encrypting integration secrets at rest
  • Integration adapters: Proxmox, Docker, NetBird, Cloudflare, AWS, Uptime Kuma, Weather, SSH (see backend/src/integrations/)

Deploy target: Docker on racknerd1 → NPM (Nginx Proxy Manager) proxy at archnest.snsnetlabs.com.

Deployment

All features are built and verified. The only remaining work to go live is wiring up the GitHub Actions deploy pipeline — the app itself does not need further development before deployment.

The workflow already exists at .github/workflows/deploy.yml and triggers on every push to main: it copies the repo to racknerd1 over SCP and runs docker compose up -d --build there. Nothing in that file needs to change. To activate it:

  1. Provision the host (racknerd1): Docker + Docker Compose installed, an SSH user the Action can authenticate as, and /opt/archnest created and owned by that user (matches DEPLOY_PATH in the workflow — change both together if a different path is wanted).
  2. Create /opt/archnest/.env on the host (Compose reads it automatically) using the repo's top-level .env.example as the template — generate real values for ARCHNEST_JWT_SECRET, ARCHNEST_SECRET_KEY, and ARCHNEST_GUAC_CRYPT_KEY (commands included inline in the example file), and set ARCHNEST_CORS_ORIGIN to the real public origin if different from the default. This file is server-side only and must never be committed.
  3. Add the deploy secrets in the GitHub repo settings (Settings → Secrets and variables → Actions): RACKNERD_HOST, RACKNERD_USER, RACKNERD_SSH_KEY (private key for that user, PEM format), and optionally RACKNERD_PORT if SSH isn't on port 22.
  4. Point DNS / Nginx Proxy Manager at the host: a proxy host for archnest.snsnetlabs.com forwarding to the container's published port (8080 for the frontend, see docker-compose.yml), with SSL handled by NPM as usual.
  5. Trigger the first deploy — either push to main, or run the workflow manually via the Actions tab (workflow_dispatch is enabled).

After that, every push to main redeploys automatically. No code changes are expected to be part of standing up this pipeline — it's configuration only (host setup, secrets, DNS/proxy).