Skip to content

Commit f616908

Browse files
committed
fix(webapp): drive the SSO upsell from the loader's entitlement decision
The client recomputed the gate from useCurrentPlan(), which is undefined wherever billing isn't configured. The server grants those deployments access, so it returned the real config surface while the page rendered the upgrade prompt over the top of it — self-hosters who installed the plugin could never reach the settings. Pass isEntitled down from the loader so there is one decision, made server-side. Removes the last plan-shaped read in the file.
1 parent a4a15d9 commit f616908

1 file changed

Lines changed: 4 additions & 11 deletions

File tree

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.sso

apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.sso/route.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import { FEATURE_FLAG } from "~/v3/featureFlags";
4747
import { dashboardAction, dashboardLoader } from "~/services/routeBuilders/dashboardBuilder";
4848
import { cn } from "~/utils/cn";
4949
import { throwPermissionDenied } from "~/utils/permissionDenied";
50-
import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route";
5150

5251
export const meta: MetaFunction = () => [{ title: "SSO & Directory Sync | Trigger.dev" }];
5352

@@ -62,13 +61,6 @@ async function resolveOrg(slug: string) {
6261
});
6362
}
6463

65-
function planAllowsSso(plan: unknown): boolean {
66-
if (!plan || typeof plan !== "object") return false;
67-
const subscription = (plan as { v3Subscription?: { plan?: { limits?: { hasSso?: boolean } } } })
68-
.v3Subscription;
69-
return subscription?.plan?.limits?.hasSso === true;
70-
}
71-
7264
// Client-side upsell is cosmetic; gate real IdP mutations server-side.
7365
async function requireSsoEntitlement(orgId: string): Promise<void> {
7466
if ((await getSsoEntitlement(orgId)) !== "entitled") {
@@ -149,6 +141,7 @@ export const loader = dashboardLoader(
149141
jitRoles: [] as Role[],
150142
directorySync: EMPTY_DIRECTORY_SYNC_STATUS,
151143
hasSso: false,
144+
isEntitled: false,
152145
});
153146
}
154147

@@ -179,6 +172,7 @@ export const loader = dashboardLoader(
179172
jitRoles,
180173
directorySync,
181174
hasSso,
175+
isEntitled: true,
182176
});
183177
}
184178
);
@@ -371,11 +365,10 @@ function useOverrideDraft<T>(serverValue: T): {
371365
}
372366

373367
export default function Page() {
374-
const { status, orgTitle, jitRoles, directorySync, hasSso } = useTypedLoaderData<typeof loader>();
368+
const { status, orgTitle, jitRoles, directorySync, hasSso, isEntitled } =
369+
useTypedLoaderData<typeof loader>();
375370
const organization = useOrganization();
376-
const _plan = useCurrentPlan();
377371

378-
const isEntitled = planAllowsSso(_plan);
379372
const activeConnections = status.connections.filter((c) => c.state === "active");
380373
const hasActive = activeConnections.length > 0;
381374

0 commit comments

Comments
 (0)