fix(plugin-auth): route invitation accept link through the Console base path#2847
Merged
Merged
Conversation
The invitation email built the accept URL directly from `config.baseUrl` with no scheme guarantee. When `baseUrl` is a bare host (e.g. `cloud.objectos.ai`), the emailed link was relative-looking and email clients wouldn't linkify it — clicking led nowhere. Route the accept URL through `getCanonicalOrigin()` and have that helper guarantee an absolute origin: prepend `https://` when the configured baseUrl has no scheme. This also hardens the OAuth issuer / consent / device-flow URLs that share the same helper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NT4mx1fHXtkxery6MtLTsp
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 9 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…se path
Verified against the objectui Console frontend: the accept-invitation page is
a React Router route (`/accept-invitation/:invitationId`) mounted under the
SPA basename (`import.meta.env.BASE_URL` = `/_console/`), the same router that
serves `/login` and `/register`. The Console's own "copy invitation link"
action builds `${origin}${BASE_URL}accept-invitation/<id>`.
The emailed link now matches that canonical form:
`${origin}${uiBasePath}/accept-invitation/<id>`, where the origin is forced
absolute (https:// prepended when baseUrl lacks a scheme) and uiBasePath
defaults to `/_console`. Previously the link was `${baseUrl}/accept-invitation/
<id>` — missing both the scheme (relative-looking, unclickable in email) and
the Console prefix (404 at the host root).
Added tests for the bare-host, explicit-scheme, and custom-uiBasePath cases.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NT4mx1fHXtkxery6MtLTsp
os-zhuang
pushed a commit
that referenced
this pull request
Jul 13, 2026
…ps origin Follow-up to the invitation-link fix (#2847). Audited every backend site that builds a user-facing link and found the same latent flaw: they read the raw `config.baseUrl`, so a bare-host value (no scheme) yielded relative-looking, unclickable links. Routed them all through the hardened getCanonicalOrigin(): - better-auth `baseURL` (583) — source of the reset-password / verify-email / magic-link email links. - OAuth `loginPage` / `consentPage` (1723-1724). - Device-authorization `verificationUri` (1811). - Phone-invite SMS `{{baseUrl}}` (sendPhoneInviteSms, 2201). Added tests: bare host promoted to https, explicit scheme/trailing slash preserved (getAuthIssuer), and better-auth baseURL carries the scheme. Full @objectstack/plugin-auth suite passes (406 tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NT4mx1fHXtkxery6MtLTsp
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.
Problem
The "accept invitation" link in invitation emails did not open. On
cloud.objectos.aithe link was missing thehttps://prefix (relative-looking, unclickable), and it also pointed at the wrong path.Root cause
sendInvitationEmailbuilt the accept URL straight fromconfig.baseUrlwith no scheme guarantee and no UI mount prefix:Two defects:
baseUrlis a bare host (e.g.cloud.objectos.ai), the result is relative-looking; email clients won't linkify it.objectuiConsole frontend: the accept-invitation page is a React Router route/accept-invitation/:invitationIdmounted under the SPA basename (import.meta.env.BASE_URL=/_console/), the same router that serves/login,/register,/oauth/consent. The Console's own "copy invitation link" action builds${origin}${BASE_URL}accept-invitation/<id>. The emailed root-path link omitted that prefix and 404'd at the host root.Fix
The link is now built to match the frontend's canonical form:
getCanonicalOrigin()is hardened to always return an absolute origin — it prependshttps://whenbaseUrlhas no scheme, and trims a trailing slash. (This also hardens the OAuth issuer / consent / device-flow URLs that share the helper.)uiBasePathprefix (default/_console, configurable for Console mounted elsewhere) matchesloginPage/consentPageconstruction already in this file and the frontend router.Result on
cloud.objectos.ai:https://cloud.objectos.ai/_console/accept-invitation/<token>.Verification
Cross-checked against
objectstack-ai/objectui:apps/console/src/App.tsx—<Route path="/accept-invitation/:invitationId">inside<BrowserRouter basename={BASENAME}>, alongside/loginand/register.packages/app-shell/.../InvitationsPage.tsx+InviteMemberDialog.tsx— the "copy link" helper builds${origin}${BASE_URL}accept-invitation/<id>.Tests
Added three cases (bare host →
https://…/_console/…; explicit scheme preserved; customuiBasePathhonoured). Full@objectstack/plugin-authsuite passes.Changeset
@objectstack/plugin-auth: patch.🤖 Generated with Claude Code