Commit Graph

44 Commits

Author SHA1 Message Date
wmantly f72e8881cf Fix mobile layout: wrap unresponsive tables, let the group filter bar wrap (#42)
Auditing mobile/responsive views turned up two classes of bug:

1. Missing .table-responsive wrapper (token.ejs and profile.ejs's other
   table already had it): admin.ejs (2 tables), invites.ejs (6 columns),
   notifications.ejs (5 columns), users.ejs (7 columns — the worst case).
   Without it these overflow the page horizontally on narrow viewports
   instead of scrolling within the table.

2. groups.ejs's search/sort/count toolbar was a plain `d-flex` (no
   flex-wrap) containing a search input, a <select> with a hard
   min-width:175px, and a nowrap count span — on a narrow viewport
   there's nowhere for that content to go but off-screen. Added
   flex-wrap and gave the search input a flex-basis so it wraps onto
   its own line first when space is tight.

Verified: EJS compiles for all five templates, npm test 192/192 pass,
and fetched each route from a running instance to confirm the fixes
are present in the served HTML.
2026-07-14 21:18:01 -04:00
wmantly 3ceeeeeca1 Clean up footer: fix copyright, move GitHub link out of the nav (#41)
- Copyright was "© <year> <name>" where <name> is conf.name — an
  operator-configurable display name (e.g. whatever CFG_ORG is set
  to), not a real copyright holder. Changed to "© <year> theta42",
  matching the LICENSE file. Also dropped "All rights reserved",
  which contradicts the MIT license this project ships under; added
  an explicit MIT License link instead.
- Moved the GitHub icon link out of the top nav (where it competed
  with actual navigation items) and into the footer, alongside the
  license link and version/build info.
- Deduplicated the identical buildVersion/buildHash/buildYear
  computation that was copy-pasted in both routes/index.js and
  routes/oauth.js into a shared nodejs/utils/build_info.js.

Verified by rendering top+bottom with the real ejs package: no
template errors, GitHub link present exactly once (in the footer,
not the nav), "All rights reserved" gone, MIT License link present.
npm test failures (155) are pre-existing/environmental (no LDAP
server here) — identical failure count with these changes stashed
out.
2026-07-14 20:54:36 -04:00
wmantly 158109de59 Documentation cleanup for public release (#38)
* docs: cleanup for public release (fix stale/wrong API docs, LICENSE, versions)

Documentation cleanup ahead of the public release announcement. Fixes a set
of confirmed issues from a prior audit:

- LICENSE: fill in MIT template placeholders (theta42, 2026).
- README.md: fix broken API docs link (api.md -> API.md), correct required
  Node.js version (13.x -> 20.x), add the missing app_sso_invite group to
  the LDAP groups table, scrub hardcoded dc=theta42,dc=com to the generic
  dc=example,dc=com used elsewhere, add a "Recommended: Docker or
  install.sh" section pointing to DEPLOYMENT.md/docs before the manual
  OpenLDAP walkthrough, and drop an emoji from a warning callout.
- nodejs/api.md: deleted — it was a stale/legacy doc with wrong routes,
  wrong request bodies, and endpoints that are dead/commented-out code.
  The root API.md is the accurate, current reference; README now links
  there directly.
- API.md: add the missing app_sso_invite permission group, fix the
  documented invite response to match the real {token, link, mail_sent}
  payload, document the previously-undocumented GET/PUT/DELETE
  /api/user/invite endpoints, add the real allowed_groups field to the
  OAuth client management examples, and document POST /api/oauth/authorize
  (the endpoint that actually issues the code after consent).
- nodejs/routes/auth.js + API.md: fix "emaill address" typo in the
  password-reset response message (source and docs kept in sync).
- DEPLOYMENT.md: fix the top-level summary to mention Redis, matching
  docs/deployment.md and the entrypoint behavior it already documents.

Flagged, not changed: tos.md reads like a personal home-lab acceptable-use
policy (Emby/Gitea/Proxmox/Discord/Signal, first-person "the admin") rather
than generic OSS docs. Left in place pending a manual decision to
genericize, relocate, or remove it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs: genericize tos.md template, track runtime-editable terms in #39

Removes operator-specific references (Emby, Gitea, Proxmox, Discord,
Signal, first-person "the admin") so the shipped tos.md reads as a
neutral starting template rather than one operator's internal policy.
Actual runtime editability (admin/legal editing terms without a code
change) is tracked in issue #39, not implemented here.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 23:21:27 -04:00
wmantly 796e013234 Fix api-tokens date display + quiet authIO no-token log (#36)
- api_tokens.ejs: created_on/last_used_on come back from Redis as strings
  (model-redis only coerces fields with an explicit `type`), so `new Date(ms)`
  yielded "Invalid date". Use `moment(ms, "x")` (the hosts.ejs/dns.ejs
  precedent) which parses a numeric string-or-number as a Unix-ms timestamp.
- api_tokens.ejs: `isExpired` is a class getter not serialized to the client
  JSON, so the "expired" badge never showed — compute expiry in the view via
  `Date.now() > Number(expires_at)`. Also guard the `last_used_on: 0` / falsy
  case (string "0" is truthy) so unset timestamps render "—" not "1970".
- middleware/auth.js: authIO did `checkToken(socket.handshake.auth.token || 0)`,
  so any socket connect without a token (login page, pre-login) did an
  `AuthToken.get(0)` lookup and logged a noisy `EntryNotFound` trace. Guard:
  reject the socket with a generic 401 when there's no token (behavior-
  preserving — unauth sockets were already rejected; just no Redis lookup / 404).

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-12 17:42:00 -04:00
wmantly b91ef2792d Add self-service API tokens (PATs) with UI + Bearer auth (#35)
Personal access tokens so scripts/CI can call the management API without a
browser session. Each logged-in user mints their own token; it authenticates as
the creator (carries their LDAP group permissions, re-resolved live), so the
existing permission.byGroup checks apply unchanged.

- models/api_token.js: new ApiToken model (sso_<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. No _ttl
  (persists; lifetime via expires_at).
- routes/api_token.js: self-service CRUD (list/get/update/delete/rotate),
  owner-scoped (created_by === req.user.uid, 403 otherwise).
- middleware/auth.js + models/auth.js: accept `Authorization: Bearer sso_...`
  (precedence over the auth-token session header); checkApiToken collapses
  every failure to one generic 401 (no existence/secret/expiry leak).
- views/api_tokens.ejs + routes/index.js (GET /api-tokens): self-service page
  (forceLogin, no group gate) — create (token shown once), edit, 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/deployment.md: API tokens section.

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-12 17:12:35 -04:00
wmantly fe9b7c168b Dockerize SSO Manager (all-in-one image) + GitHub Pages docs
All-in-one Dockerfile.openldap bundling the app + OpenLDAP + Redis in one
container, plus an idempotent bare-metal install.sh, and a Jekyll docs site
for GitHub Pages:
- Dockerfile.openldap (node:20-alpine; openldap + pw-sha2/ppolicy/memberof/
  refint; dumb-init PID 1; npm ci --omit=dev; tos.md copied to /).
- docker-entrypoint.sh: generate slapd.conf (mdb + overlays + TLS + indexes +
  access), self-signed LDAPS cert, seed directory tree + required groups,
  bundled redis, export app_* config, exec node.
- docker-compose.yml, .dockerignore, DEPLOYMENT.md, secrets.js.example.
- install.sh: idempotent Debian/Ubuntu bare-metal installer (Node 20.x,
  OpenLDAP, Redis, systemd unit) with flags + --dry-run/--skip-ldap/--skip-app.
- ops/ldif/: memberof/refint/tls/index/nodes/logging LDIFs.
- nodejs/conf/base.js: generic defaults (dc=example,dc=com / localhost /
  SSO Manager) so per-deployment values move to secrets.js or app_* env.
- nodejs/package.json: bump @simpleworkjs/conf to ^1.1.0 (app_* env overrides).
- nodejs/routes/index.js: /health endpoint for healthchecks.
- docs/: _config.yml + index/deployment/configuration/oauth/ldap pages
  (jekyll-theme-cayman) for GitHub Pages from /docs.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-11 17:03:16 -04:00
wmantly 4f432ec448 oauth edit 2026-07-11 00:54:49 -04:00
wmantly bb79247054 oath grpup fixes 2026-07-02 16:49:22 -04:00
wmantly 93df047a21 oath fixes 2026-07-02 16:22:16 -04:00
wmantly cf2418a9eb Login page 2026-07-01 12:08:11 -04:00
wmantly c92dbe4aa6 Testing fix 2026-07-01 11:40:38 -04:00
wmantly 5644bfa5ec Updated frontend 2026-07-01 11:10:09 -04:00
wmantly ee21bdbf22 Added app name to conf file 2024-02-19 10:52:06 -05:00
wmantly 24d5364da0 Corrected email address 2024-02-19 10:49:37 -05:00
wmantly e132015871 Added error message when non-admin cant see groups 2024-02-19 10:42:40 -05:00
wmantly 2a6aaafa3d Added permission to block non admins from seeing all users 2024-02-19 10:42:02 -05:00
wmantly 2654c31f68 name error fixed 2021-04-28 12:55:36 -04:00
wmantly 1022d9da86 name error fixed 2021-04-28 12:52:59 -04:00
wmantly 623e52e135 started token API 2021-03-23 00:41:12 -04:00
wmantly b97970c8de Updated packages 2021-03-23 00:40:22 -04:00
wmantly 0e212c48cc added white lable name 2021-03-23 00:36:53 -04:00
wmantly 96a97c1d6d Moved timestamps to footer for user cards 2020-12-31 16:07:22 -05:00
wmantly b56094841f Editing a user updates the card and shows a message 2020-12-31 15:19:39 -05:00
wmantly 07f3c8b023 Permission based on owners of groups 2020-12-31 15:00:02 -05:00
wmantly cb51fae2f6 added group owners 2020-12-31 09:53:44 -05:00
wmantly 2c89d42569 Limit action message from finding more then 1 div 2020-12-31 03:01:09 -05:00
wmantly 746ee6e62a Fixed spacing for nav icons 2020-12-30 18:41:08 -05:00
wmantly 5143162510 Better error message failed removing user 2020-12-30 15:27:06 -05:00
wmantly b9d2304974 Added function to check group permission. 2020-12-30 14:33:07 -05:00
wmantly b05ac1aca7 removed some error output for 401 2020-12-30 14:30:45 -05:00
wmantly 4591c640db removed some error output for 404 2020-12-30 13:32:54 -05:00
wmantly adf073bab7 Forced user names to be lowercase. 2020-12-30 13:21:18 -05:00
wmantly f9ee94cccd updated npm packages 2020-12-30 13:20:55 -05:00
wmantly 51b6deee8f localy sourced JS/CSS 2020-10-04 14:48:44 -04:00
wmantly afd1ed867a uped NPM packages 2020-10-04 14:20:12 -04:00
wmantly 99a17c83ba added font awseome localy 2020-10-04 14:18:42 -04:00
wmantly e7a022cc29 zoom fixes 2020-08-08 20:52:24 -04:00
wmantly fb3e6ca7dc front end fixes 2020-07-01 16:08:19 -04:00
wmantly b8f632e644 user edit 2020-05-15 15:17:57 -04:00
wmantly 0889832efc groups and reset 2020-05-15 00:40:15 -04:00
wmantly e71fccd27c icons 2020-05-05 23:28:46 -04:00
wmantly 4d51a4ac9e rc1 2020-05-05 23:07:00 -04:00
wmantly f2309463a4 beta 2020-05-03 18:28:11 -04:00
wmantly 8dc0e946b1 beta 2020-05-03 18:22:51 -04:00