Commit Graph
36 Commits
Author SHA1 Message Date
Junv (via Hermes) a8d12caafb fix(ha): enable HTTPS with Let's Encrypt via Cloudflare proxy
- Removed ssl-redirect annotation (now proper HTTPS)
- Added tls section matching other service patterns
- Updated home.junv.cc DNS to use Cloudflare proxy
- Certificate issued by letsencrypt-prod via HTTP-01 through Cloudflare
2026-07-25 15:44:16 +10:00
Junv (via Hermes) 8aabf71f79 fix: add fallback for root-level static files in site-content handler
When an HTML page references static files (images, CSS, JS) via
relative URLs, the browser resolves them as root-level paths
(e.g. /image.jpg from page /site-name). Without a trailing slash
on the page URL, these resolve to /image.jpg instead of
/site-name/image.jpg.

The API's /site-content/{path} handler interprets the first path
segment as the site name, so /dule_yuan_15k.jpg was treated as a
site name lookup rather than a file within the dule-yuan site.

Added _find_static_file() fallback: when no site matches the first
path segment, search all site directories for a matching filename.
Only triggered for common static file extensions to avoid
ambiguous lookups.
2026-07-13 11:19:50 +10:00
Junv (via Hermes) 570442bb0d fix: quote X-Forwarded-For header_up to avoid Caddy v2 replace mode dropping headers
- Both /api/* and catch-all handlers now use quoted Caddy placeholder
  syntax (e.g. "{http.request.header.X-Forwarded-For}") so Caddy evaluates
  them in 'set' mode instead of failing silently in 'replace' mode.
- demo-service-caddy.yaml ConfigMap: also added missing X-Forwarded-For
  header_up in the catch-all handler (was entirely absent).
2026-07-13 11:12:20 +10:00
Junv (via Hermes) afbf6e2931 fix(caddy): remove broken header_up X-Forwarded-For from catch-all handler - nginx already sets it 2026-07-13 11:06:36 +10:00
Junv (via Hermes) fb1b29e066 fix(caddy): handle_path / instead of handle / to stop intercepting all routes 2026-07-13 11:01:27 +10:00
Junv (via Hermes) 7a8a7a6a5e fix(demo-service): correct is_internal_ip() logic bug + add login link to fallback error page 2026-07-13 10:57:14 +10:00
Junv (via Hermes) cf631b2b3e demo-service: fix internal IP detection — preserve X-Forwarded-For chain
- Caddy was overwriting X-Forwarded-For with {remote_host} (nginx
  ingress pod IP), losing the original client IP from nginx ingress
- Fix: preserve upstream X-Forwarded-For and append Caddy's remote
- Add X-Real-IP fallback in is_internal_ip() for extra safety
- Clean up the caddy-config ConfigMap accordingly
2026-07-13 10:43:19 +10:00
Junv (via Hermes) dd7528e437 demo-service: add Cache-Control no-store to HTML content responses
Prevents browser from caching old responses that had wrong
Content-Disposition header before the .draft/.bak fix.
2026-07-13 10:37:43 +10:00
Junv (via Hermes) da9b71ea45 demo-service: fix DB migration — add visibility column to existing tables
ALTER TABLE ADD COLUMN fails silently if column already exists
(rather than crashing on startup).
2026-07-13 10:27:52 +10:00
Junv (via Hermes) 2679287543 demo-service: add three-tier visibility (disabled/internal/public)
- Replace old enabled/published fields with single visibility field:
  - disabled → 404 for everyone (admin sees in admin UI only)
  - internal → 192.168.1.x access without auth; external → 404
  - public → anyone can access
- Admin users can see all sites via admin UI regardless of visibility
- Add /api/sites/{name}/visibility endpoint to change visibility
- Keep backward-compat enable/disable/publish/unpublish endpoints
- Database auto-migration from old enabled+published to new visibility
- NFS-safe sync_visibility hides/shows index.html per mode
2026-07-13 10:23:29 +10:00
Junv (via Hermes) c069b1f5ff demo-service: fix .draft/.bak HTML files downloaded instead of rendered
The site_content endpoint only checked for .html suffix to render
inline. Hidden HTML fallbacks (.index.html.draft, .index.html.bak)
have .draft or .bak suffixes, so they fell through to FileResponse
which triggered browser download instead of rendering.

Fix: also check for .draft and .bak suffixes.
2026-07-13 10:10:57 +10:00
Junv (via Hermes) ad1904c441 demo-service: add login link to error page, mount ConfigMap into API container
- Add subtle 'Log in' link to 401/403/404 error page
- Link redirects through pass.junv.cc OAuth with return URL
- Mount error-page-html ConfigMap into API container too (so both
  Caddy and API serve the same updated error page)
- Define error-page-html ConfigMap in repo for ArgoCD management
2026-07-13 10:06:18 +10:00
Junv (via Hermes) 6afccdb765 fix: add DISCORD_ALLOW_BOTS=all to curio-agent so it can see 小黑's messages 2026-07-11 16:56:16 +10:00
Junv (via Hermes) db6587585e feat: add curio-agent manifest (privacy-protected Discord recommendation bot)
- Hermes Agent instance running as Discord bot WhatToDo#3542
- Restricted tools: only web/search, no terminal/file/system access
- DISCORD_ALLOW_ALL_USERS=true + require_mention for access control
- NetworkPolicy restricts egress to internet only (no internal network)
- Secret removed from manifest — managed via kubectl create secret
2026-07-11 16:26:36 +10:00
Junv (via Hermes) 950fa76eea feat(demo-service): migrate metadata to SQLite
- New _db.py module with sqlite3-based persistence
- Auto-migrate from sites.json on first run
- All writes now use _db.insert/update/delete directly
- Sites default to draft (published: false) on creation

The sites.json file is kept as .json.migrated for safety
2026-06-14 12:43:50 +10:00
Junv (via Hermes) 492ed0c3e5 fix(demo-service): move Caddyfile to dedicated ConfigMap manifest
- Extract Caddyfile from demo-service.yaml into demo-service-caddy.yaml
- ArgoCD auto-applies both files; Caddyfile changes are tracked in git
- Fixes issue where Caddyfile updates in the source dir weren't reaching the pod
2026-06-14 12:25:48 +10:00
Junv (via Hermes) c72f12ad8e ci: trigger workflow to bump PLACEHOLDER image 2026-06-14 12:17:22 +10:00
Junv (via Hermes) 89ccee86bd fix(demo-service): move imagePullSecrets to pod-level
K8s ignores imagePullSecrets at container-level; it must be at pod spec level.
This is why the pull was failing with 401.
2026-06-14 12:13:37 +10:00
Junv (via Hermes) cbb50ac941 ci(demo-service): move manifest to home-apps/ root for ArgoCD
- ArgoCD 'home-apps' app tracks the home-apps/ directory at root level only
- Move k8s-manifest.yaml to home-apps/demo-service.yaml (sibling of other apps)
- Keep source code (Dockerfile, service.py, etc.) in home-apps/demo-service/ subdirectory
- Update workflow to update the new path
- Also fix imagePullSecrets placement (pod-level not container-level)
2026-06-14 12:10:22 +10:00
Junv (via Hermes) 49703c4c8f ci(demo-service): fix sed regex to match both old and new image references 2026-06-14 12:02:10 +10:00
Junv (via Hermes) 425955b921 ci(demo-service): GitHub Actions workflow for ghcr.io build
- .github/workflows/build-demo-service.yml builds on push when home-apps/demo-service/**
- Pushes to ghcr.io/wahyd4/demo-manager with git SHA tag + :latest
- Updates k8s-manifest.yaml with new image tag
- ArgoCD picks up the new image on next sync

k8s-manifest changes:
- image: ghcr.io/wahyd4/demo-manager (was docker.io/library/demo-manager)
- imagePullPolicy: Always
- imagePullSecrets: github-image-pull-secret (auth for ghcr.io)
2026-06-14 11:59:52 +10:00
Junv (via Hermes) 031f39bae6 fix(demo-service): force inline Content-Disposition to prevent download
- All responses (HTML, CSS, JS, images) now have Content-Disposition: inline
- Add Cache-Control: no-store to bust any cached attachment response
- 401/404 error pages: inline, text/html, no-store
2026-06-14 11:49:52 +10:00
Junv (via Hermes) cc0fe77749 fix(demo-service): render HTML inline instead of download
- FileResponse sets Content-Disposition: attachment by default
- Switch to HTMLResponse for .html files to render in browser
2026-06-14 11:45:34 +10:00
Junv (via Hermes) c76e3f86a8 fix(demo-service): drafts accessible when authenticated
- New /site-content endpoint serves files with visibility+auth check
- All paths proxied through API (not Caddy file_server)
- Drafts: 401 canvas page (no auth) or 200 content (with auth)
- Nonexistent: 404 canvas page
- Preserves proper HTTP status codes
2026-06-14 11:43:33 +10:00
Junv (via Hermes) a8a09c6675 fix(demo-service): restore admin UI, add canvas error page for 401/403/404
- admin-ui.html extracted from git history
- Caddy handle_errors serves canvas page for all HTML errors
- Error page served directly by Caddy (correct status code preserved)
- Republished hermes-stats and my-awesome-demo
- Modular file structure: _config.py, _loaders.py, admin-ui.html, error-page.html
2026-06-14 11:36:04 +10:00
Junv (via Hermes) 10a055d37c feat(demo-service): canvas particle animation error page
- Chill canvas animation with floating particles + connections
- 'This page isnt available right now' friendly message
- Modular file structure: _config.py + _loaders.py for env vars and HTML
- No login method exposed on error page
2026-06-14 11:29:42 +10:00
Junv (via Hermes) 0dfb2eaa36 feat(demo-service): minimal SVG-animated access-restricted page
- Replaces login page with pure SVG animation (no login buttons)
- Animated lock icon, pulsing dots, orbiting ring, breathing circles
- Lightweight — zero dependencies, pure CSS/SVG
2026-06-14 11:22:09 +10:00
Junv (via Hermes) ad75449e0d feat(demo-service): beautiful login-required page for /admin
- Replaces 401 JSON with styled HTML error page
- Glassmorphism card with Pocket ID SSO sign-in button
- New sites default to draft (published: false)
2026-06-14 11:20:30 +10:00
Junv (via Hermes) b694a317d4 fix(demo-service): site title opens new tab unless disabled 2026-06-14 11:15:29 +10:00
Junv (via Hermes) 7edfe2cfa4 fix(demo-service): always render site name as clickable link
- Published sites: link to public URL
- Draft sites: link with dashed underline → opens preview modal
2026-06-14 11:11:36 +10:00
Junv (via Hermes) 4dce2be3d4 feat(demo-service): add publish/unpublish draft system with preview
- Sites now start as drafts (published: false) — hidden from public
- Publish endpoint makes site live at demo.junv.cc/<name>
- Unpublish hides it back to draft
- Preview endpoint serves draft HTML to authenticated users
- Caddy blocks .draft/.bak files (defense-in-depth)
- Backward compatible: existing sites default to published
- sync_visibility() handles all state transitions
2026-06-14 11:10:25 +10:00
Junv (via Hermes) 3e36501eba fix: Caddy routing for /admin without trailing slash 2026-06-14 10:59:14 +10:00
Junv (via Hermes) d4484e6750 feat: add Demo Service — Caddy + FastAPI for hosting demo sites at demo.junv.cc
- Caddy as static file server + reverse proxy
- FastAPI management API with Pocket ID SSO
- Web UI at demo.junv.cc/admin
- Agent API with Bearer token auth
- Demo sites accessible at demo.junv.cc/<folder-name>
- NFS PVC for persistent storage
- Enable/disable per-site
2026-06-14 10:57:36 +10:00
Junv (via Hermes) 3a860bb486 remove: K8s security-audit cronjob (path not available on node, switching to Hermes cron) 2026-06-13 15:26:14 +10:00
Junv (via Hermes) e99ec79ae5 add: cronjob for weekly security audit (Sat 7:50 AM) 2026-06-13 15:20:38 +10:00
Junv (via Hermes) a8b6890a99 chore: upgrade Docker images batch — June 2026
Updates 7 Docker images across the infrastructure manifests (PG14 kept as-is):

  media/jackett.yaml
    linuxserver/jackett: 0.24.1124 → 0.24.1985 (patch)

  media/media.yaml
    linuxserver/qbittorrent: version-5.1.2-r4 → version-5.2.1_v2.0.12 (major 5.1→5.2)

  home-apps/n8n.yaml
    n8nio/n8n: 2.15.0 → 2.23.1 (minor)

  db/qdrant.yaml
    qdrant/qdrant: v1.16-unprivileged → v1.18.1-unprivileged (minor)

  kube-vip/daemonset.yaml
    kube-vip/kube-vip: v0.4.4 → v0.9.2 (conservative, stayed within v0.x)

  on-demand/once-etcd-job.yaml
    etcd: 3.5.1-0 → 3.5.30-0 (patch)

  adhoc-config/oauth2-proxy.yaml
    oauth2-proxy/oauth2-proxy: v7.6.0 → v7.15.2 (minor)

Note: postgres:14 kept unchanged per PR review feedback.
kube-vip kept at v0.9.2 (latest v0.x) instead of v1.2.0 to avoid
v0→v1 breaking changes.
2026-06-01 16:52:51 +10:00