Skip to content

feat(portal): redirect to return_to on expired_jwt_token - #2

Merged
rrader26 merged 1 commit into
mainfrom
feat/portal-redirect-on-expired-jwt
May 23, 2026
Merged

feat(portal): redirect to return_to on expired_jwt_token#2
rrader26 merged 1 commit into
mainfrom
feat/portal-redirect-on-expired-jwt

Conversation

@rrader26

Copy link
Copy Markdown

When a customer-portal JWT expires (12h TTL), every GraphQL query errors with expired_jwt_token and the user sees broken Something went wrong cards in each section. They have no way to recover without going back to the host app.

This PR adds a recovery path: if the portal URL was minted with return_to=, the Apollo error handler bounces the user there with refresh=1 appended. The host app then generates a fresh portal URL — same browser tab, no error screen.

Behavior

  • return_to present + expired_jwt_token: window.location.href to return_to with refresh=1 (one-shot guarded)
  • return_to absent: unchanged (generic error UI)
  • Any other error code: unchanged

Companion changes

  • ThinkfleetAI/lago-api PR: return_to query param on GET /customers/:id/portal_url
  • Host app /billing reads refresh=1 and uses same-tab redirect mode

Test plan

  • Generate portal URL with return_to=https://example.com, expire JWT, refresh → navigates to https://example.com?refresh=1
  • Without return_to + expired JWT → unchanged generic error UI
  • Only one redirect fires even with 5+ concurrent GraphQL errors

When the customer portal JWT expires, the Apollo error handler now reads
the ?return_to query param off the current URL and redirects there with
?refresh=1 appended. This lets a host app self-heal stale portal tabs by
generating a fresh portal URL on the refresh=1 visit.

If return_to isn't in the URL (token was minted without it), the current
behavior is unchanged — sections render the generic "Something went wrong"
state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rrader26
rrader26 merged commit 75e2dff into main May 23, 2026
5 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant