Skip to content

Commit 56e301e

Browse files
authored
fix(webapp): gate SSO UI on plugin presence, not managed-cloud (#4006)
`isManagedCloud` was a wrong way to gate the SSO feature, system now checks if SSO_ENABLED is set, and if the plugin is available
1 parent 5052d89 commit 56e301e

3 files changed

Lines changed: 12 additions & 20 deletions

File tree

apps/webapp/app/components/navigation/OrganizationSettingsSideMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export function OrganizationSettingsSideMenu({
147147
data-action="roles"
148148
/>
149149
)}
150-
{isManagedCloud && isSsoUsingPlugin && (
150+
{isSsoUsingPlugin && (
151151
<SideMenuItem
152152
name="SSO"
153153
icon={PadlockIcon}

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

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import { Paragraph } from "~/components/primitives/Paragraph";
3131
import { Select, SelectItem } from "~/components/primitives/Select";
3232
import { Switch } from "~/components/primitives/Switch";
3333
import { $replica } from "~/db.server";
34-
import { featuresForRequest } from "~/features.server";
3534
import { useOrganization } from "~/hooks/useOrganizations";
3635
import { rbac } from "~/services/rbac.server";
3736
import { ssoController } from "~/services/sso.server";
@@ -79,12 +78,8 @@ export const loader = dashboardLoader(
7978
authorization: { action: "manage", resource: { type: "sso" } },
8079
},
8180
async ({ context, request }) => {
82-
const { isManagedCloud } = featuresForRequest(request);
83-
// Gate on managed cloud AND the SSO plugin actually being loaded
84-
// (SSO_ENABLED off → OSS fallback → isUsingPlugin false). Without
85-
// this the page renders for every managed-cloud org even when SSO
86-
// is disabled for the deployment.
87-
if (!isManagedCloud || !(await ssoController.isUsingPlugin())) {
81+
// True only when SSO_ENABLED is on and a real SSO plugin is loaded.
82+
if (!(await ssoController.isUsingPlugin())) {
8883
throw new Response("Not Found", { status: 404 });
8984
}
9085

@@ -175,8 +170,8 @@ export const action = dashboardAction(
175170
throw new Response("Not Found", { status: 404 });
176171
}
177172

178-
const { isManagedCloud } = featuresForRequest(request);
179-
if (!isManagedCloud) {
173+
// Mirror the loader gate.
174+
if (!(await ssoController.isUsingPlugin())) {
180175
throw new Response("Not Found", { status: 404 });
181176
}
182177
await requireSsoEntitlement(orgId);

apps/webapp/app/routes/login._index/route.tsx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { FormError } from "~/components/primitives/FormError";
1313
import { Header1 } from "~/components/primitives/Headers";
1414
import { Paragraph } from "~/components/primitives/Paragraph";
1515
import { TextLink } from "~/components/primitives/TextLink";
16-
import { featuresForRequest } from "~/features.server";
1716
import { isGithubAuthSupported, isGoogleAuthSupported } from "~/services/auth.server";
1817
import { getLastAuthMethod } from "~/services/lastAuthMethod.server";
1918
import { commitSession, setRedirectTo } from "~/services/redirectTo.server";
@@ -86,16 +85,14 @@ export async function loader({ request }: LoaderFunctionArgs) {
8685
? "Your SSO session expired. Please sign in again."
8786
: null;
8887

89-
const { isManagedCloud } = featuresForRequest(request);
90-
// /login is unauthenticated and high-traffic; don't pay the plugin
91-
// resolution + flag fetch on self-hosted where the result is unused.
88+
// SSO login requires both an active plugin (SSO_ENABLED on + a real plugin loaded)
89+
// and the hasSso global flag — a DB-backed runtime kill switch that disables the
90+
// SSO login button without a redeploy. isUsingPlugin() is cheap and short-circuits
91+
// before the flag fetch, so self-hosted/no-plugin deployments pay nothing.
9292
let showSsoAuth = false;
93-
if (isManagedCloud) {
94-
const [pluginActive, globalFlags] = await Promise.all([
95-
ssoController.isUsingPlugin(),
96-
getGlobalFlags(),
97-
]);
98-
showSsoAuth = pluginActive && (globalFlags as Record<string, unknown>).hasSso === true;
93+
if (await ssoController.isUsingPlugin()) {
94+
const globalFlags = await getGlobalFlags();
95+
showSsoAuth = (globalFlags as Record<string, unknown>).hasSso === true;
9996
}
10097

10198
if (redirectTo) {

0 commit comments

Comments
 (0)