- Dashboard, Sessions, and Audit pages now wrap their content in
<div class="container mt-4">, matching sso-manager-node/proxy's width
instead of rendering full-bleed inside the fluid shell.
- Audit's nav entry now carries groups: ['admin'] (utils/ui.js), reusing
the existing synthetic-admin-group nav-gating convention -- the API
route was already server-side admin-gated, this closes the last gap by
hiding the nav link/page for non-admins too.
- app-base.js (byte-identical across the 3 apps): added
app.util.revealItem() and the --sw-content-offset sticky-positioning
variable, carried over from the same round of changes in
sso-manager-node/proxy. Not yet called anywhere in this app -- no
sticky/reveal use case here yet -- but keeps the shared file in sync.
views/top.ejs, views/bottom.ejs and public/lib/js/app-base.js are now
byte-identical across sso-manager-node, proxy and jump-host. Everything
per-app moved into utils/ui.js, exposed to every render as `ui` via
app.locals (nav items + their group gates, footer repo/docs/ToS links,
favicon, profile/logout targets, update-banner on/off + label).
Client framework changes:
- One gating model everywhere: app-base.js reveals .group-required-<cn>
for each of the current user user/me groups. sso-manager-node sends LDAP
DNs in memberOf, the OIDC clients send CNs in groups; both normalise to
CNs, and the clients isAdmin flag becomes a synthetic `admin` group, so
proxy nav-admin items are now group-required-admin.
- user/me is fetched once per page load and cached (app.auth.loadUser);
nav, forceLogin and group-required elements all read that one promise.
- isLoggedIn is dual-mode (Promise + node-style callback), so the async
and callback call styles both work from one shared top.ejs.
- forceLogin no longer uses $.holdReady (removed in jQuery 4): it redirects
to /login?redirect=<path>, and still enforces required groups.
- logOut only clears the session; the caller decides where to go next.
- post/put/delete are dual-mode Promise/callback, which also removes the
undefined `callback2` reference that threw on a non-function callback.
Dependencies: jquery ^4.0.0 and ejs ^3.1.10 in all three apps.
jump-host specifics:
- .group-required base rule added to styles.css (no gated nav items yet).
- #spa-shell drops its inline margin-top; styles.css already sets it, and
the shared shell adjusts it when a banner is shown.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>