Repository navigation
Migrate off bento-auth-js onto Auth.js (next-auth v5) - #443
Merged
Merged
Conversation
Adds a next-auth v5 config (custom OIDC provider against the same identity provider, JWT sessions with manual refresh-token rotation) and its Route Handler, and wires SessionProvider into the app. This lands next to the still-active bento-auth-js so the new plumbing can be reviewed in isolation before consumers are switched over.
Adds src/js/features/auth/ (resources, permission strings, and a
resource-permissions Redux slice, all ported from bento-auth-js since
they're Bento's own authorization-service contract, not part of the
OIDC library) and repoints every component/hook that used
bento-auth-js at it and at next-auth's useSession()/signIn()/signOut().
Session state (access/id tokens) now lives in Auth.js's own session,
not Redux/localStorage. Redux thunks that need the access token
synchronously (they only have getState(), no hook access) get it via
a small mirror kept in sync by useSyncAccessToken(), dispatched once
near the app root - the token itself is never persisted to
localStorage the way it used to be.
Sign-out now also ends the identity provider's own session
(RP-initiated logout via end_session_endpoint), matching prior
behaviour, via a small session-independent discovery route since
next-auth has no built-in support for it.
Per the migration plan, the popup-window reauth flow and the
localStorage-flag-driven auto-reauth ("was signed in, try silently
signing in again") are both dropped rather than ported: Auth.js's
persistent session cookie plus refresh-on-read already covers what
auto-reauth was for, and popup reauth would mean building custom code
back on top of the thing this migration is meant to simplify.
bento-auth-js itself is still a listed dependency for now; removing
it and the dead code it leaves behind (the token-refresh Web Worker)
is the next step.
Removes bento-auth-js and its hand-built postinstall step now that nothing in the app imports it, and deletes the token-refresh Web Worker it needed (bento-auth-js used it to work around setInterval throttling in inactive tabs; SessionProvider's refetchInterval plus its refetchOnWindowFocus default cover the same need without a dedicated worker).
Auth.js's own config validation requires `issuer` even though `wellKnown` is what it actually fetches from at request time - without it, every request throws InvalidEndpoints and /api/auth/session 500s. Derive it from OPENID_CONFIG_URL by stripping the well-known suffix.
…nstead of duplicating them The Auth.js migration copied bento-auth-js's Resource type, permission string constants, and makeAuthorizationHeader verbatim into features/auth/ purely to drop the dependency - none of that is OIDC-related, it's Bento's own authorization-service contract. Keeping bento-auth-js as a dependency and importing those pieces directly avoids maintaining a duplicate copy. features/auth/authSlice.ts and hooks.ts stay as local code: they're genuinely new logic bridging Auth.js's session to the resource- permission cache, not something bento-auth-js's own (differently wired) Redux slice and hooks can serve.
SanjeevLakhwani
marked this pull request as ready for review
September 9, 2026 17:20
SanjeevLakhwani
force-pushed
the
feat/next-migration-step1
branch
from
September 9, 2026 20:14
323efef to
8c6921d
Compare
# Conflicts: # package-lock.json
Previously a RefreshTokenError just sat on the session, so every subsequent session check retried the same dead refresh token against the identity provider and logged the same invalid_grant error forever.
v-rocheleau
reviewed
Sep 11, 2026
v-rocheleau
left a comment
Contributor
There was a problem hiding this comment.
Great direction for the changes, will make it a lot easier to use bento public with various OIDC providers with confidential clients, great for PCGL.
Just have 1 env vars question I wanted to ask before going deeper in the review.
SanjeevLakhwani
force-pushed
the
feat/authjs-migration
branch
from
September 16, 2026 14:57
81b77fb to
9c2cdba
Compare
davidlougheed
requested changes
Sep 22, 2026
getProjects ran on mount, before the session resolved and its token was mirrored into Redux, so signed-in users' project list was fetched without an Authorization header and never refetched. Gate that fetch and the loader on a new useIsAuthReady hook, which stays true across token refreshes so it doesn't re-trigger fetches.
Read BENTO_PUBLIC_SESSION_REFETCH_INTERVAL_SECONDS (default 120) through the runtime config like the other display/auth settings, instead of a hardcoded constant.
…nd sign-in The provider id was written as a literal in both auth.ts and the client hooks, and it also forms the /api/auth/callback/<id> path. Move it to a dependency-free constants module both sides can import.
# Conflicts: # package-lock.json # package.json # src/js/components/SiteHeader.tsx
# Conflicts: # src/js/App.tsx
davidlougheed
requested changes
Sep 30, 2026
davidlougheed
left a comment
Member
There was a problem hiding this comment.
- update igv.js code to use access token from features/auth?
…-js's Main added IGV track support using bento-auth-js's useAccessToken, which reads from a Redux auth slice bento-auth-js no longer populates on this branch. It happened to work by coincidence (our slice also has an accessToken field), but relies on an internal implementation detail rather than the session. Use our own hook instead.
…rect performSignOut() clears the session client-side before redirecting to the identity provider to end its session too, so isAuthenticated flips false mid-callback and the button flashed to Sign In right before the page navigated away. Track sign-out locally and keep the button loading instead.
davidlougheed
requested changes
Oct 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SessionProvider's session cookie + refetch behavior covers the same ground nativelyRelated infra changes (separate repos, not in this PR)
AUTH_SECRETenv var;AUTH_URLoverride for Auth.js: Configure Bento Public auth: AUTH_SECRET, AUTH_URL, cert SAN, and session refetch interval bento#373gateway:proxy_large_headers.confnow included for thepubliclocation block - Auth.js's callback response sets several large cookies at once, which exceeded nginx's default header buffer: Fix 502 on auth callback caused by large Auth.js response headers bento_gateway#27