refactor(desloppify): SSO login-page route, CLAUDE.md rewrite, gitignore cleanup
- sso-gate.js: add GET /api/v1/auth/login-page?service= route; auto-login HTML for chat/plex/jellyfin/emby now served from code instead of inline Caddyfile respond blobs. Fix merge() try-block syntax error (was missing closing } before catch, breaking Jellyfin/Emby localStorage merge). - middleware.js: add /api/v1/auth/login-page to PUBLIC_ROUTES. - CLAUDE.md: complete rewrite — was describing the old Windows-local C:/caddy/ layout; now accurately describes DNS2 production (paths, container, caddy-apply workflow, SSO architecture, common mistakes). - .gitignore: cover runtime JSON/log/cert files that were sitting untracked in dev root (audit-log, backup-history, credentials, health-history, etc.), plus generated-certs/, pki/, assets/. - Remove tracked dev-root noise: comprehensive-test.js, license-keygen.js, test-security-fixes.js (scripts that don't belong at repo root). - Remove stale routes/openclaw.js (leftover from old monolithic structure). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
5f6c25d2e3
commit
a2e6566958
@@ -10,217 +10,149 @@
|
||||
- When deploying new containers, always use `E:/dockerdata/<app-name>/` for bind mount paths
|
||||
- For CIFS volumes in docker-compose, use `//Sami-pc/e_share/dockerdata/...` as the device path
|
||||
|
||||
## CRITICAL: Production vs Development Paths
|
||||
## CRITICAL: Production is on DNS2 (not this machine)
|
||||
|
||||
DashCaddy runs on **DNS2** (`100.121.150.22` via Tailscale / `194.233.88.206` public).
|
||||
SSH in with: `ssh root@100.121.150.22`
|
||||
|
||||
### Production Layout on DNS2
|
||||
|
||||
### Production Files (LIVE - what actually runs)
|
||||
```
|
||||
C:/caddy/
|
||||
├── Caddyfile # Active Caddy configuration
|
||||
├── services.json # Services shown on dashboard
|
||||
├── dns-credentials.json # DNS API credentials
|
||||
├── config.json # DashCaddy configuration
|
||||
└── sites/
|
||||
└── status/ # Dashboard frontend files
|
||||
└── assets/ # Logos, fonts, icons
|
||||
/opt/dashcaddy/ # git repo (auto-updated)
|
||||
├── dashcaddy-api/
|
||||
│ ├── *.js # API server source
|
||||
│ └── data/
|
||||
│ ├── services.json # LIVE services list
|
||||
│ ├── config.json # LIVE DashCaddy config
|
||||
│ ├── dns-credentials.json # DNS API credentials
|
||||
│ └── credentials.json # Encrypted app credentials
|
||||
├── status/ # Dashboard frontend (built)
|
||||
│ ├── index.html
|
||||
│ ├── dist/ # Bundled JS (core/features/onboarding/init)
|
||||
│ ├── js/ # Source JS (also served statically)
|
||||
│ ├── css/
|
||||
│ └── assets/
|
||||
├── ca/ # DashCA static site
|
||||
├── updates/ # Auto-updater staging + history
|
||||
└── start.sh # Container launch script (run by @reboot cron)
|
||||
```
|
||||
|
||||
### Development Files (for editing/testing)
|
||||
### Docker Container
|
||||
|
||||
- **Name**: `dashcaddy-api`
|
||||
- **Image**: `dashcaddy-dashcaddy-api:latest`
|
||||
- **Port**: `127.0.0.1:3001` (Caddy proxies to it)
|
||||
- **Started by**: `/opt/dashcaddy/start.sh` via root `@reboot` cron
|
||||
|
||||
Key container mounts:
|
||||
| Container path | Host path |
|
||||
|---|---|
|
||||
| `/app/data/` | `/opt/dashcaddy/dashcaddy-api/data/` |
|
||||
| `/app/assets` | `/opt/dashcaddy/status/assets` |
|
||||
| `/caddyfile` | `/etc/caddy/Caddyfile` |
|
||||
| `/app/backups` | `/opt/dashcaddy/backups` |
|
||||
|
||||
### Caddy
|
||||
|
||||
- **Config**: `/etc/caddy/Caddyfile` (git-guarded — edit then run `caddy-apply`)
|
||||
- **Admin API**: `http://localhost:2019` (NOT 2021)
|
||||
- **TLS storage**: `/var/lib/caddy/`
|
||||
- **Static files**: Caddy serves `/opt/dashcaddy/status/` for `status.sami`
|
||||
|
||||
### Development Files (for editing)
|
||||
|
||||
```
|
||||
e:/CaddyCerts/sites/
|
||||
├── caddy-api/
|
||||
│ ├── server.js # API server source code
|
||||
│ ├── app-templates.js # Docker app templates (52+ apps)
|
||||
│ ├── services.json # DEV ONLY - not used in production!
|
||||
├── dashcaddy-api/ # API server source (NOT caddy-api/)
|
||||
│ ├── server.js
|
||||
│ ├── src/app.js # Express app factory
|
||||
│ ├── routes/ # Route handlers
|
||||
│ ├── middleware.js
|
||||
│ └── ...
|
||||
└── status/
|
||||
└── index.html # Dashboard UI source
|
||||
└── status/ # Dashboard frontend source
|
||||
├── index.html # HTML template (~853 lines)
|
||||
├── js/ # Source JS modules
|
||||
├── css/
|
||||
├── dist/ # Built output (run node build.js)
|
||||
└── build.js # Build script (uses esbuild)
|
||||
```
|
||||
|
||||
## Docker Container Mount Points
|
||||
|
||||
The `caddy-api` container mounts production files:
|
||||
|
||||
| Container Path | Host Path (Production) |
|
||||
|----------------|------------------------|
|
||||
| `/app/services.json` | `C:/caddy/services.json` |
|
||||
| `/app/dns-credentials.json` | `C:/caddy/dns-credentials.json` |
|
||||
| `/caddyfile` | `C:/caddy/Caddyfile` |
|
||||
| `/app/assets` | `C:/caddy/sites/status/assets` |
|
||||
|
||||
## When Making Changes
|
||||
|
||||
### To add/remove services from dashboard:
|
||||
Edit `C:/caddy/services.json` (NOT e:/CaddyCerts/sites/caddy-api/services.json)
|
||||
Edit `/opt/dashcaddy/dashcaddy-api/data/services.json` on DNS2 directly,
|
||||
OR use the dashboard UI at `https://status.sami`.
|
||||
|
||||
### To modify Caddy reverse proxy rules:
|
||||
Edit `C:/caddy/Caddyfile`, then reload via:
|
||||
```bash
|
||||
curl -X POST http://localhost:2019/load -H "Content-Type: text/caddyfile" --data-binary @"C:/caddy/Caddyfile"
|
||||
ssh root@100.121.150.22
|
||||
# Edit /etc/caddy/Caddyfile
|
||||
caddy-apply "reason for change" # validates + reloads + git commits
|
||||
```
|
||||
|
||||
### To modify API server code:
|
||||
Edit `e:/CaddyCerts/sites/caddy-api/server.js`, then:
|
||||
1. Copy to production: `C:/caddy/sites/caddy-api/`
|
||||
2. Restart container: `docker restart caddy-api`
|
||||
1. Edit `e:/CaddyCerts/sites/dashcaddy-api/` locally
|
||||
2. `scp` changed files to `root@100.121.150.22:/opt/dashcaddy/dashcaddy-api/`
|
||||
3. Rebuild container: `ssh root@100.121.150.22 "bash /opt/dashcaddy/start.sh"`
|
||||
|
||||
### To modify app templates:
|
||||
Edit `e:/CaddyCerts/sites/caddy-api/app-templates.js`
|
||||
(Templates are loaded at runtime, changes require container restart)
|
||||
### To modify dashboard frontend:
|
||||
1. Edit source in `e:/CaddyCerts/sites/status/js/` or `status/index.html`
|
||||
2. Build: `cd e:/CaddyCerts/sites/status && node build.js`
|
||||
3. Deploy: `scp -r dist/ index.html sw.js root@100.121.150.22:/opt/dashcaddy/status/`
|
||||
|
||||
### To modify dashboard UI:
|
||||
Edit `e:/CaddyCerts/sites/status/index.html`
|
||||
Copy to `C:/caddy/sites/status/` for production
|
||||
|
||||
### To modify DashCA (CA certificate distribution):
|
||||
### To modify DashCA:
|
||||
Edit files in `e:/CaddyCerts/sites/ca/`, then:
|
||||
1. Regenerate certificate formats: `cd e:/CaddyCerts/sites/ca/scripts && bash generate-all.sh`
|
||||
2. Copy to production: `cp -r e:/CaddyCerts/sites/ca/* C:/caddy/sites/ca/`
|
||||
3. Reload Caddy if Caddyfile changes were made
|
||||
1. Regenerate: `cd e:/CaddyCerts/sites/ca/scripts && bash generate-all.sh`
|
||||
2. Deploy: `scp -r e:/CaddyCerts/sites/ca/* root@100.121.150.22:/opt/dashcaddy/ca/`
|
||||
|
||||
## DashCA - Certificate Authority Distribution
|
||||
|
||||
**Purpose**: Provides a one-click installation page for the root CA certificate, allowing users to easily trust *.sami domains on any device.
|
||||
|
||||
**Access**: https://ca.sami (or https://ca.yourdomain for other installations)
|
||||
|
||||
### File Locations
|
||||
|
||||
**Development (for editing):**
|
||||
```
|
||||
e:/CaddyCerts/sites/ca/
|
||||
├── index.html # Landing page
|
||||
├── root.crt, root.der # Certificate formats
|
||||
├── root.mobileconfig # Apple profile
|
||||
├── intermediate.crt # Intermediate CA
|
||||
├── cert-info.json # Certificate metadata
|
||||
├── scripts/
|
||||
│ ├── install.ps1 # Windows installer
|
||||
│ ├── install.sh # Linux/macOS installer
|
||||
│ ├── generate-cert-info.js # Extract cert metadata
|
||||
│ ├── generate-mobileconfig.js # Generate Apple profile
|
||||
│ └── generate-all.sh # Regenerate all formats
|
||||
└── assets/ # Icons, logos
|
||||
```
|
||||
|
||||
**Production (served by Caddy):**
|
||||
```
|
||||
C:/caddy/sites/ca/
|
||||
├── index.html
|
||||
├── root.crt, root.der
|
||||
├── root.mobileconfig
|
||||
├── install.ps1, install.sh
|
||||
└── assets/
|
||||
```
|
||||
|
||||
### Certificate Source
|
||||
|
||||
Caddy's built-in PKI generates certificates at:
|
||||
- **Root CA**: `C:/caddy/certs/pki/authorities/local/root.crt`
|
||||
- **Intermediate CA**: `C:/caddy/certs/pki/authorities/local/intermediate.crt`
|
||||
**Purpose**: One-click CA cert install page so *.sami domains are trusted on all devices.
|
||||
**Access**: `https://ca.sami`
|
||||
|
||||
**Certificate Info:**
|
||||
- **CN**: Sami Home Network Root CA
|
||||
- **Algorithm**: ECDSA P-256 with SHA-256
|
||||
- **Valid Until**: Dec 22, 2034 (~10 years)
|
||||
- **Valid Until**: Dec 22, 2034
|
||||
- **Fingerprint**: `08:98:A5:63:F5:A1:A2:58:5F:02:D7:A8:A2:54:87:E6:BC:33:96:21:29:0E`
|
||||
|
||||
### Deployment
|
||||
|
||||
DashCA is a **static site** (not Docker-based), deployed via the app selector:
|
||||
1. Navigate to App Selector in dashboard
|
||||
2. Find "DashCA" in Security category
|
||||
3. Click Deploy
|
||||
4. System automatically:
|
||||
- Creates `C:/caddy/sites/ca/` directory
|
||||
- Copies files from development directory
|
||||
- Generates certificate formats (DER, mobileconfig)
|
||||
- Adds ca.sami block to Caddyfile
|
||||
- Reloads Caddy configuration
|
||||
- Registers service in `services.json`
|
||||
|
||||
### Updating Certificates
|
||||
|
||||
When Caddy's CA certificate is renewed (every ~10 years):
|
||||
|
||||
```bash
|
||||
# 1. Regenerate all certificate formats
|
||||
cd e:/CaddyCerts/sites/ca/scripts
|
||||
bash generate-all.sh
|
||||
|
||||
# 2. Update fingerprint in installation scripts
|
||||
# Edit install.ps1 - update $ExpectedFingerprint
|
||||
# Edit install.sh - update EXPECTED_FP
|
||||
|
||||
# 3. Copy to production
|
||||
cp -r e:/CaddyCerts/sites/ca/* C:/caddy/sites/ca/
|
||||
|
||||
# 4. Notify users via dashboard or email
|
||||
```
|
||||
**Certificate Source** (on DNS2):
|
||||
- Root CA: `/etc/ssl/sami-ca/root.crt`
|
||||
- Intermediate CA: auto-generated by Caddy at `/var/lib/caddy/pki/authorities/local/`
|
||||
|
||||
### API Endpoints
|
||||
|
||||
- **GET /api/ca/info** - Returns certificate metadata (name, fingerprint, expiration, etc.)
|
||||
- **GET /api/health/ca** - Returns CA expiration health status
|
||||
- `healthy`: >90 days remaining
|
||||
- `warning`: 30-90 days remaining
|
||||
- `critical`: <30 days remaining
|
||||
|
||||
### Caddyfile Configuration
|
||||
|
||||
DashCA's Caddyfile block (auto-generated on deployment):
|
||||
- **Root**: `C:/caddy/sites/ca`
|
||||
- **TLS**: Internal (uses Caddy's local CA)
|
||||
- **MIME Types**: Proper headers for .crt, .der, .mobileconfig, .ps1, .sh files
|
||||
- **SPA Fallback**: Rewrites non-file requests to /index.html
|
||||
- **Cache Control**: Certificates cached for 24h, HTML not cached
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
- **Windows**: PowerShell installer (installs to LocalMachine\Root store)
|
||||
- **macOS**: .mobileconfig profile or command-line installer
|
||||
- **Linux**: Shell installer (Debian, RedHat, Arch)
|
||||
- **iOS**: .mobileconfig profile (requires manual trust in Settings)
|
||||
- **Android**: Direct .crt download (installs as user certificate)
|
||||
|
||||
### Landing Page Features
|
||||
|
||||
- Automatic OS detection
|
||||
- QR code for mobile access
|
||||
- Certificate info display (loaded from `/api/ca/info`)
|
||||
- Platform-specific installation instructions
|
||||
- Copy-to-clipboard for fingerprint and commands
|
||||
- Download links for all certificate formats
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
**Issue**: Certificate fingerprint mismatch during installation
|
||||
**Cause**: CA certificate was renewed
|
||||
**Solution**: Regenerate certificates and update fingerprints in install scripts
|
||||
|
||||
**Issue**: *.sami sites still show warnings after CA install
|
||||
**Cause**: Browser may have cached the untrusted state
|
||||
**Solution**: Clear browser cache, restart browser, or visit site in incognito mode
|
||||
|
||||
**Issue**: iOS doesn't trust certificate after profile install
|
||||
**Cause**: iOS requires manual trust enablement
|
||||
**Solution**: Settings → General → About → Certificate Trust Settings → Enable trust
|
||||
- `GET /api/ca/info` — certificate metadata
|
||||
- `GET /api/health/ca` — CA expiration health (`healthy` / `warning` / `critical`)
|
||||
|
||||
## Key Services
|
||||
|
||||
| Service | Port | Description |
|
||||
|---------|------|-------------|
|
||||
| Caddy (HTTPS) | 443 | Reverse proxy |
|
||||
| Caddy Admin | 2019 | Caddy API (note: NOT 2021) |
|
||||
| DashCaddy API | 3001 | Dashboard backend |
|
||||
| DNS2 (Primary) | 100.74.102.61:5380 | Technitium DNS |
|
||||
| DNS1 (Secondary) | 192.168.254.204:5380 | Technitium DNS |
|
||||
| Service | Where | Port | Notes |
|
||||
|---------|-------|------|-------|
|
||||
| Caddy (HTTPS) | DNS2 | 443 | Reverse proxy |
|
||||
| Caddy Admin | DNS2 | 2019 | Caddy API |
|
||||
| DashCaddy API | DNS2 | 3001 | Dashboard backend (container) |
|
||||
| Technitium DNS (primary) | DNS2 | 5380 | `100.121.150.22` |
|
||||
| Technitium DNS (secondary) | DNS1 (this PC) | 5380 | `100.71.97.12` |
|
||||
|
||||
## SSO Architecture
|
||||
|
||||
`import dashcaddy_auth <serviceId>` in the Caddyfile expands to a `forward_auth` gate that:
|
||||
1. Checks the DashCaddy TOTP session (cookie domain `.sami` — shared across all `*.sami`)
|
||||
2. Injects credentials (API key, Basic Auth, app cookies) into upstream request headers
|
||||
|
||||
For client-side auto-login (chat, Plex, Jellyfin, Emby):
|
||||
- Caddy redirects `path /` to `/dashcaddy-login`
|
||||
- `/dashcaddy-login` proxies to `GET /api/v1/auth/login-page?service=<id>` on the API
|
||||
- That page's JS fetches `/dashcaddy-api/api/auth/app-token/<id>` and stores the token in `localStorage`
|
||||
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
1. **Wrong services.json**: The API container reads from `C:/caddy/services.json`, not the development copy
|
||||
2. **Caddy admin port**: It's 2019, not 2021 (check with `netstat` if unsure)
|
||||
3. **DNS server**: DNS2 (100.74.102.61) is PRIMARY, DNS1 is secondary
|
||||
4. **Caddyfile not reloaded**: After editing, must POST to /load endpoint or restart Caddy
|
||||
1. **Wrong API source dir**: It's `dashcaddy-api/`, NOT `caddy-api/` (old name, no longer exists)
|
||||
2. **Wrong services file**: Edit the one in `/opt/dashcaddy/dashcaddy-api/data/` on DNS2, not the dev copy
|
||||
3. **Caddyfile edits without caddy-apply**: Always use `caddy-apply` — it validates, reloads, and git-commits
|
||||
4. **Caddy admin port**: It's 2019, not 2021
|
||||
5. **Frontend changes without build**: Edit JS source, then `node build.js`, then deploy `dist/`
|
||||
6. **DNS2 Tailscale IP**: `100.121.150.22` (NOT the old `100.104.4.5` or `100.74.102.61`)
|
||||
|
||||
---
|
||||
|
||||
@@ -316,3 +248,4 @@ vi /opt/dashcaddy/services.json # live-reloaded by the watcher
|
||||
- **Purpose**: Unified management for Docker + Caddy + DNS
|
||||
- **Local TLD (Windows)**: `.sami`
|
||||
- **Local TLD (Linux, DNS2)**: `.home` (default; configurable via `siteConfig.tld`)
|
||||
- **Repo**: `/opt/dashcaddy/` on DNS2 (git, auto-updated by self-updater)
|
||||
|
||||
Reference in New Issue
Block a user