Commit Graph

13 Commits

Author SHA1 Message Date
wmantly d5df5baca1 Add DuckDNS as a free DNS provider option (#124)
DuckDNS's API is smaller than the other providers' (no list/read API,
no arbitrary sub-records, one A/AAAA + one TXT record per domain), so
domains are entered by the operator instead of auto-discovered, and
getRecords reads from public DNS since there's nothing else to query.
Documented as a free option in the README and DNS provider docs.
2026-07-13 23:41:09 -04:00
wmantly 5139fbb79a Documentation cleanup for public release (#123)
Prepares the docs for the public release announcement: removes obsolete/dead
material, fixes drift between the API reference and the actual routes, and
standardizes on the default GitHub Pages URL.

- Remove Vagrant entirely: delete Vagrantfile, docs/dev_setup.md, and stale
  vagrant references in .gitignore/.dockerignore; rewrite openresty/README.md
  to describe the actual (currently unused) directory and point to
  ops/nginx_conf/ for the real OpenResty config.
- Delete docs/Update 4.11.md (personal scratch changelog) and drop both its
  and dev_setup.md's references from docs/README.md's Legacy Documentation
  section.
- Remove checkmark emoji from docs/contributing.md's PR Requirements list.
- Bring the auth model docs up to date with the code: document
  GET /api/auth/oidc/start + /callback, the /api/permission and /api/group
  RBAC routers, the /api/dns/dynamic/* sub-API, and /api/api-token (self
  -service PATs) in both nodejs/api.md and docs/api.md; add the missing
  "Clear Host Cache" section; drop the invite-token/SSH-key endpoints that no
  longer exist in nodejs/routes/user.js; note admin-only routes. Mention
  OIDC/LDAP/RBAC as core features in README.md.
- Keep nodejs/api.md and docs/api.md fully in sync (same body, differing only
  in Jekyll front matter / relative links) instead of letting them drift.
- Fix Node.js version references (20.x -> 22.x) in README.md and
  docs/installation.md to match ops/install.sh and the Dockerfile.
- Note that the manual nginx-conf/systemd install steps in README.md and
  docs/installation.md won't auto-track repo changes the way install.sh's
  symlink approach does, and recommend install.sh.
- Update the stale test/unit file lists in docs/contributing.md and
  nodejs/test/README.md to match the actual directory contents.
- Add npm run test:integration to README.md's Running Tests section.
- Add nodejs/conf/, nodejs/controller/, and nodejs/migrations/ to the project
  structure diagrams in README.md, docs/architecture.md, and
  docs/contributing.md.
- Standardize "CloudFlare" -> "Cloudflare" everywhere to match the actual API
  value in nodejs/models/dns_provider.js.
- Add the missing app_auth__adminGroups row to DEPLOYMENT.md's app_* table.
- Delete docs/CNAME (custom domain) so GitHub Pages serves from the default
  https://theta42.github.io/proxy/, matching docs/README.md.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 23:20:59 -04:00
wmantly 3df7d8c5cb install.sh: OpenResty repo distro/component fix for Debian (#122)
Follow-up to #121: the repo line still used the live codename + "main", but
the openresty.org Debian tree only publishes up to bookworm (no trixie) and
uses the "openresty" component, not "main". Verified against the repo:
  /package/debian/dists/  -> bookworm bullseye buster jessie stretch (no trixie)
  bookworm Release        -> Components: openresty
  /package/ubuntu/dists/  -> noble jammy focal ... ; Components: main

So:
- Debian: distro = host codename when published (jessie..bookworm), else
  bookworm (binary-compatible with trixie, same OpenSSL 3 era); component
  "openresty".
- Ubuntu/Mint: distro = host codename; component "main" (unchanged).

Produces the working line on a trixie host:
  deb [...] http://openresty.org/package/debian bookworm openresty

docs/installation.md manual steps updated to match.

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-13 20:41:51 -04:00
wmantly 6158a3a693 install.sh: support Debian 13 (trixie) OpenResty repo (#121)
Two issues on Debian 13 (Trixie):

1. apt's sequoia GPG backend now rejects SHA-1 signatures, and the OpenResty
   repo signing key is still SHA-1 — so `apt-get update` fails to verify the
   repo. When /usr/share/apt/default-sequoia.config is present (Debian 13+),
   install a back-end override that extends the SHA-1 acceptance window to
   2028 (the OpenResty key is expected to rotate to a stronger algorithm;
   revisit before then). No-op on older Debian/Ubuntu. Idempotent on re-run.

2. The repo path was hardcoded to /package/ubuntu with the host codename,
   which worked on older Debian by coincidence. trixie lives under
   /package/debian, so pick the tree by distro ID (debian -> /package/debian,
   else -> /package/ubuntu).

docs/installation.md: mirror both changes in the manual install steps, with a
note that install.sh applies the sequoia override automatically.

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-13 18:12:44 -04:00
wmantly a9a48c3445 Add self-service API tokens (PATs) with UI + Bearer auth (#119)
Personal access tokens so scripts/CI can call the management API without an
OIDC browser session. Each logged-in user mints their own token; it
authenticates as the creator (groups snapshotted at mint, mirroring the proxy's
browser AuthToken), and the existing authz layer (Permission.effectiveFor /
roles.resolveEffective) applies unchanged. Local groups and owned-domain rights
are recomputed live; only SSO/LDAP group membership is the mint-time snapshot.

- models/api_token.js: new ApiToken model (prx_<id>_<secret> format; id is the
  lookup key, secret bcrypt-hashed + isPrivate, shown once). add()/rotate()/
  authenticate(); optional expires_at; best-effort last_used_on; groups
  snapshot. No _ttl (persists). Deliberately NOT wrapped in ModelPs (so the
  last_used_on write on the auth path doesn't spam the socket).
- routes/api_token.js: self-service CRUD (list/get/update/delete/rotate),
  owner-scoped (created_by === reqUsername(req), 403 otherwise).
- middleware/auth.js + models/auth.js: accept `Authorization: Bearer prx_...`
  (precedence over the auth-token session header). Builds a synthetic req.token
  that satisfies the only three req.token reads (auth.js .user/.groupsArray,
  authz.js reqUsername .created_by) so the authz layer works unchanged.
  checkApiToken collapses every failure to one generic 401 (no leak).
- views/api_tokens.ejs + routes/render.js (GET /api-tokens): self-service page
  (forceLogin, no admin gate) — create (token shown once), rotate, revoke.
- views/top.ejs: "API Tokens" nav entry visible to all logged-in users.
- public/js/app.js: app.apiToken client module.
- DEPLOYMENT.md + docs/docker.md: API tokens section.

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-12 17:12:38 -04:00
wmantly 8e78604a37 Persist Redis (AOF+vol), read config from mounted secrets.js, add backup/restore docs (#118)
Lossless upgrades + config story for the all-in-one proxy image.

Redis persistence (Part A):
- Replace in-memory `--save "" --appendonly no` with AOF + RDB persisted to
  /data. Host records, permissions, DNS creds, local users, AND the
  lua-resty-auto-ssl Let's Encrypt certs now all survive container recreation
  (persisting Redis persists the cert store — no LE re-issue / rate-limit on
  rebuild).
- Add the `proxy-data` named volume -> /data in docker-compose.yml; fix the
  stale "in-memory, lost on recreation" comment.

Config from ./config/proxy-secrets.js (Part B):
- docker-entrypoint.sh: when /config/proxy-secrets.js is mounted, symlink it to
  /app/conf/secrets.js so @simpleworkjs/conf reads the oidc/ldap/auth config
  from the file. No app_* env should then be passed (app_* beats secrets.js).
  Falls back to app_* env when the file is absent (standalone still works).
- docker-compose.yml: drop all app_oidc__* / app_ldap__* / app_auth__* env and
  add `./config:/config:ro`. Keep RESOLVER/REAL_IP_FROM/NODE_ENV/NODE_PORT
  (OpenResty-runtime / process env, not app_* config). No env_file.
- New secrets.js.example (the proxy had none): oidc (enabled, endpoints,
  clientId/clientSecret, redirectUri, scopes, claims), ldap (url, bindDN,
  bindPassword, searchBase, userFilter, tlsOptions), auth (adminGroups,
  adminUsers, groupRoleMap), plus an orchestrator-only `stack` key.

Backup/restore docs:
- Full "Backups and restore" runbook in DEPLOYMENT.md (what lives where, manual
  backup, Redis restore with the AOF-vs-RDB note — AOF wins on startup so the
  AOF must be deleted before an RDB load; restoring Redis restores cert state
  at snapshot time; migrations note). Update the Setup + Auto-SSL sections.
- docs/docker.md: update Quick start + How configuration works + Auto-SSL for
  the new ./config/ approach (app_* env now advanced/optional).

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-12 13:00:34 -04:00
wmantly 94ad6143cc Dockerize the proxy (all-in-one image) + Docker docs
All-in-one Dockerfile bundling OpenResty + the Node mgmt app + Redis in one
container, mirroring the bare-metal ops/install.sh layout:
- Dockerfile (openresty/openresty:1.31.1.1-2-bookworm-fat base; dumb-init PID 1;
  luarocks install lua-resty-auto-ssl/luasocket/lua-resty-ipmatcher; node 22.x;
  npm ci --omit=dev; OpenResty confs + lua copied into place).
- docker-entrypoint.sh: fallback cert, sed-parameterize RESOLVER/REAL_IP_FROM,
  start bundled redis + node app, exec openresty foreground.
- docker-compose.yml (standalone), .dockerignore, DEPLOYMENT.md.
- nodejs/routes/render.js: /health endpoint for healthchecks.
- nodejs/models/user_ldap.js: tlsOptions forwarded to ldapts Client so the
  proxy can bind ldaps:// with a self-signed cert (app_ldap__tlsOptions__*).
- nodejs/package.json: bump @simpleworkjs/conf to ^1.1.0 (app_* env overrides).
- docs/docker.md + index.md: Docker deployment guide + fronting an SSO Manager.
- ops/proxy.service: add WorkingDirectory=/var/www/proxy/nodejs (bare-metal
  cwd fix so relative conf/ paths resolve).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-11 17:02:52 -04:00
wmantly 5309719622 Create CNAME 2026-02-11 11:21:00 -05:00
wmantly b78376cdf9 Add model-redis package references to documentation
- Added ORM reference in architecture.md (Redis section)
- Added Data Models section in contributing.md with example
- Updated README.md to mention model-redis in Architecture
- Linked to https://www.npmjs.com/package/model-redis for more info

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 20:35:55 -05:00
wmantly 3dc9e22dc5 Fix architecture documentation - clarify Redis-first lookup
- OpenResty checks Redis FIRST for every request
- Node.js is only queried as fallback when Redis has no entry
- Cached hosts continue working even if Node.js goes down
- Updated diagram to show lookup hierarchy
- Restructured caching strategy to emphasize L1/L2 tiers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 17:37:54 -05:00
wmantly 354abdf19b Gitpage added 2025-12-31 16:51:27 -05:00
wmantly 663fd0f949 update docs 2020-04-11 16:57:57 -04:00
wmantly 9eca40e0d2 docs 2019-06-30 21:58:02 -04:00