[refactor]: Remove isSSOEnabled logic throughout the codebase (#9462)

Eliminated all references to `isSSOEnabled` across the frontend,
backend, and configuration files. This change simplifies the codebase by
removing unnecessary feature flag checks, associated logic, and
environment variables. The SSO feature remains available without
reliance on this flag.
This commit is contained in:
Antoine Moreaux
2025-01-10 14:45:35 +01:00
committed by GitHub
parent e58edc3bc1
commit 5648c3b31c
18 changed files with 22 additions and 101 deletions

View File

@ -178,7 +178,6 @@ export type ClientConfig = {
defaultSubdomain?: Maybe<Scalars['String']>;
frontDomain: Scalars['String'];
isMultiWorkspaceEnabled: Scalars['Boolean'];
isSSOEnabled: Scalars['Boolean'];
sentry: Sentry;
signInPrefilled: Scalars['Boolean'];
support: Support;
@ -335,7 +334,6 @@ export enum FeatureFlagKey {
IsJsonFilterEnabled = 'IsJsonFilterEnabled',
IsMicrosoftSyncEnabled = 'IsMicrosoftSyncEnabled',
IsPostgreSqlIntegrationEnabled = 'IsPostgreSQLIntegrationEnabled',
IsSsoEnabled = 'IsSSOEnabled',
IsStripeIntegrationEnabled = 'IsStripeIntegrationEnabled',
IsUniqueIndexesEnabled = 'IsUniqueIndexesEnabled',
IsViewGroupsEnabled = 'IsViewGroupsEnabled',
@ -2082,7 +2080,7 @@ export type UpdateBillingSubscriptionMutation = { __typename?: 'Mutation', updat
export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>;
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, isMultiWorkspaceEnabled: boolean, isSSOEnabled: boolean, defaultSubdomain?: string | null, frontDomain: string, debugMode: boolean, analyticsEnabled: boolean, chromeExtensionId?: string | null, canManageFeatureFlags: boolean, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl?: string | null, billingFreeTrialDurationInDays?: number | null }, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean, microsoft: boolean, sso: Array<{ __typename?: 'SSOIdentityProvider', id: string, name: string, type: IdentityProviderType, status: SsoIdentityProviderStatus, issuer: string }> }, support: { __typename?: 'Support', supportDriver: string, supportFrontChatId?: string | null }, sentry: { __typename?: 'Sentry', dsn?: string | null, environment?: string | null, release?: string | null }, captcha: { __typename?: 'Captcha', provider?: CaptchaDriverType | null, siteKey?: string | null }, api: { __typename?: 'ApiConfig', mutationMaximumAffectedRecords: number } } };
export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, isMultiWorkspaceEnabled: boolean, defaultSubdomain?: string | null, frontDomain: string, debugMode: boolean, analyticsEnabled: boolean, chromeExtensionId?: string | null, canManageFeatureFlags: boolean, billing: { __typename?: 'Billing', isBillingEnabled: boolean, billingUrl?: string | null, billingFreeTrialDurationInDays?: number | null }, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean, microsoft: boolean, sso: Array<{ __typename?: 'SSOIdentityProvider', id: string, name: string, type: IdentityProviderType, status: SsoIdentityProviderStatus, issuer: string }> }, support: { __typename?: 'Support', supportDriver: string, supportFrontChatId?: string | null }, sentry: { __typename?: 'Sentry', dsn?: string | null, environment?: string | null, release?: string | null }, captcha: { __typename?: 'Captcha', provider?: CaptchaDriverType | null, siteKey?: string | null }, api: { __typename?: 'ApiConfig', mutationMaximumAffectedRecords: number } } };
export type SkipSyncEmailOnboardingStepMutationVariables = Exact<{ [key: string]: never; }>;
@ -3493,7 +3491,6 @@ export const GetClientConfigDocument = gql`
}
signInPrefilled
isMultiWorkspaceEnabled
isSSOEnabled
defaultSubdomain
frontDomain
debugMode

View File

@ -14,7 +14,6 @@ export const AppRouter = () => {
const isCRMMigrationEnabled = useIsFeatureEnabled(
FeatureFlagKey.IsCrmMigrationEnabled,
);
const isSSOEnabled = useIsFeatureEnabled(FeatureFlagKey.IsSsoEnabled);
const isServerlessFunctionSettingsEnabled = useIsFeatureEnabled(
FeatureFlagKey.IsFunctionSettingsEnabled,
);
@ -32,7 +31,6 @@ export const AppRouter = () => {
isBillingPageEnabled,
isCRMMigrationEnabled,
isServerlessFunctionSettingsEnabled,
isSSOEnabled,
isAdminPageEnabled,
)}
/>

View File

@ -266,7 +266,6 @@ type SettingsRoutesProps = {
isBillingEnabled?: boolean;
isCRMMigrationEnabled?: boolean;
isServerlessFunctionSettingsEnabled?: boolean;
isSSOEnabled?: boolean;
isAdminPageEnabled?: boolean;
};
@ -274,7 +273,6 @@ export const SettingsRoutes = ({
isBillingEnabled,
isCRMMigrationEnabled,
isServerlessFunctionSettingsEnabled,
isSSOEnabled,
isAdminPageEnabled,
}: SettingsRoutesProps) => (
<Suspense fallback={<SettingsSkeletonLoader />}>
@ -391,12 +389,10 @@ export const SettingsRoutes = ({
/>
<Route path={SettingsPath.Releases} element={<Releases />} />
<Route path={SettingsPath.Security} element={<SettingsSecurity />} />
{isSSOEnabled && (
<Route
path={SettingsPath.NewSSOIdentityProvider}
element={<SettingsSecuritySSOIdentifyProvider />}
/>
)}
<Route
path={SettingsPath.NewSSOIdentityProvider}
element={<SettingsSecuritySSOIdentifyProvider />}
/>
{isAdminPageEnabled && (
<>
<Route path={SettingsPath.AdminPanel} element={<SettingsAdmin />} />

View File

@ -28,7 +28,6 @@ export const useCreateAppRouter = (
isBillingEnabled?: boolean,
isCRMMigrationEnabled?: boolean,
isServerlessFunctionSettingsEnabled?: boolean,
isSSOEnabled?: boolean,
isAdminPageEnabled?: boolean,
) =>
createBrowserRouter(
@ -65,7 +64,6 @@ export const useCreateAppRouter = (
isServerlessFunctionSettingsEnabled={
isServerlessFunctionSettingsEnabled
}
isSSOEnabled={isSSOEnabled}
isAdminPageEnabled={isAdminPageEnabled}
/>
}

View File

@ -9,7 +9,6 @@ import { isAnalyticsEnabledState } from '@/client-config/states/isAnalyticsEnabl
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
import { isDeveloperDefaultSignInPrefilledState } from '@/client-config/states/isDeveloperDefaultSignInPrefilledState';
import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState';
import { isSSOEnabledState } from '@/client-config/states/isSSOEnabledState';
import { sentryConfigState } from '@/client-config/states/sentryConfigState';
import { supportChatState } from '@/client-config/states/supportChatState';
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
@ -30,7 +29,6 @@ export const ClientConfigProviderEffect = () => {
const setIsMultiWorkspaceEnabled = useSetRecoilState(
isMultiWorkspaceEnabledState,
);
const setIsSSOEnabledState = useSetRecoilState(isSSOEnabledState);
const setBilling = useSetRecoilState(billingState);
const setSupportChat = useSetRecoilState(supportChatState);
@ -107,7 +105,6 @@ export const ClientConfigProviderEffect = () => {
setChromeExtensionId(data?.clientConfig?.chromeExtensionId);
setApiConfig(data?.clientConfig?.api);
setIsSSOEnabledState(data?.clientConfig?.isSSOEnabled);
setDomainConfiguration({
defaultSubdomain: data?.clientConfig?.defaultSubdomain,
frontDomain: data?.clientConfig?.frontDomain,
@ -129,7 +126,6 @@ export const ClientConfigProviderEffect = () => {
setIsAnalyticsEnabled,
error,
setDomainConfiguration,
setIsSSOEnabledState,
setAuthProviders,
setCanManageFeatureFlags,
]);

View File

@ -22,7 +22,6 @@ export const GET_CLIENT_CONFIG = gql`
}
signInPrefilled
isMultiWorkspaceEnabled
isSSOEnabled
defaultSubdomain
frontDomain
debugMode

View File

@ -1,6 +0,0 @@
import { createState } from '@ui/utilities/state/utils/createState';
export const isSSOEnabledState = createState<boolean>({
key: 'isSSOEnabledState',
defaultValue: false,
});

View File

@ -1,7 +1,6 @@
import styled from '@emotion/styled';
import { H2Title, IconLock, Section, Tag } from 'twenty-ui';
import { isSSOEnabledState } from '@/client-config/states/isSSOEnabledState';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsReadDocumentationButton } from '@/settings/developers/components/SettingsReadDocumentationButton';
import { SettingsSSOIdentitiesProvidersListCard } from '@/settings/security/components/SettingsSSOIdentitiesProvidersListCard';
@ -9,9 +8,6 @@ import { SettingsSecurityOptionsList } from '@/settings/security/components/Sett
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
import { SettingsPath } from '@/types/SettingsPath';
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { useRecoilValue } from 'recoil';
import { FeatureFlagKey } from '~/generated/graphql';
const StyledContainer = styled.div`
width: 100%;
@ -29,10 +25,6 @@ const StyledSSOSection = styled(Section)`
`;
export const SettingsSecurity = () => {
const isSSOEnabled = useRecoilValue(isSSOEnabledState);
const isSSOSectionDisplay =
useIsFeatureEnabled(FeatureFlagKey.IsSsoEnabled) && isSSOEnabled;
return (
<SubMenuTopBarContainer
title="Security"
@ -47,23 +39,21 @@ export const SettingsSecurity = () => {
>
<SettingsPageContainer>
<StyledMainContent>
{isSSOSectionDisplay && (
<StyledSSOSection>
<H2Title
title="SSO"
description="Configure an SSO connection"
adornment={
<Tag
text={'Enterprise'}
color={'transparent'}
Icon={IconLock}
variant={'border'}
/>
}
/>
<SettingsSSOIdentitiesProvidersListCard />
</StyledSSOSection>
)}
<StyledSSOSection>
<H2Title
title="SSO"
description="Configure an SSO connection"
adornment={
<Tag
text={'Enterprise'}
color={'transparent'}
Icon={IconLock}
variant={'border'}
/>
}
/>
<SettingsSSOIdentitiesProvidersListCard />
</StyledSSOSection>
<Section>
<StyledContainer>
<H2Title

View File

@ -3,7 +3,6 @@ import { CaptchaDriverType, ClientConfig } from '~/generated/graphql';
export const mockedClientConfig: ClientConfig = {
signInPrefilled: true,
isMultiWorkspaceEnabled: false,
isSSOEnabled: false,
authProviders: {
google: true,
magicLink: false,

View File

@ -36,7 +36,6 @@ FRONT_PORT=3001
# AUTH_GOOGLE_CLIENT_SECRET=replace_me_with_google_client_secret
# AUTH_GOOGLE_CALLBACK_URL=http://localhost:3000/auth/google/redirect
# AUTH_GOOGLE_APIS_CALLBACK_URL=http://localhost:3000/auth/google-apis/get-access-token
# AUTH_SSO_ENABLED=false
# SERVERLESS_TYPE=local
# STORAGE_TYPE=local
# STORAGE_LOCAL_PATH=.local-storage

View File

@ -50,11 +50,6 @@ export const seedFeatureFlags = async (
workspaceId: workspaceId,
value: true,
},
{
key: FeatureFlagKey.IsSSOEnabled,
workspaceId: workspaceId,
value: true,
},
{
key: FeatureFlagKey.IsGmailSendEmailScopeEnabled,
workspaceId: workspaceId,

View File

@ -65,9 +65,6 @@ export class ClientConfig {
@Field(() => Boolean)
isMultiWorkspaceEnabled: boolean;
@Field(() => Boolean)
isSSOEnabled: boolean;
@Field(() => String, { nullable: true })
defaultSubdomain: string;

View File

@ -29,7 +29,6 @@ export class ClientConfigResolver {
microsoft: this.environmentService.get('AUTH_MICROSOFT_ENABLED'),
sso: [],
},
isSSOEnabled: this.environmentService.get('AUTH_SSO_ENABLED'),
signInPrefilled: this.environmentService.get('SIGN_IN_PREFILLED'),
isMultiWorkspaceEnabled: this.environmentService.get(
'IS_MULTIWORKSPACE_ENABLED',

View File

@ -24,7 +24,6 @@ import { LLMTracingDriver } from 'src/engine/core-modules/llm-tracing/interfaces
import { CacheStorageType } from 'src/engine/core-modules/cache-storage/types/cache-storage-type.enum';
import { CaptchaDriverType } from 'src/engine/core-modules/captcha/interfaces';
import { AssertOrWarn } from 'src/engine/core-modules/environment/decorators/assert-or-warn.decorator';
import { CastToBoolean } from 'src/engine/core-modules/environment/decorators/cast-to-boolean.decorator';
import { CastToLogLevelArray } from 'src/engine/core-modules/environment/decorators/cast-to-log-level-array.decorator';
import { CastToPositiveNumber } from 'src/engine/core-modules/environment/decorators/cast-to-positive-number.decorator';
@ -232,11 +231,6 @@ export class EnvironmentVariables {
@ValidateIf((env) => env.AUTH_GOOGLE_ENABLED)
AUTH_GOOGLE_CALLBACK_URL: string;
@CastToBoolean()
@IsOptional()
@IsBoolean()
AUTH_SSO_ENABLED = false;
@IsString()
@IsOptional()
ENTERPRISE_KEY: string;
@ -459,16 +453,6 @@ export class EnvironmentVariables {
@IsString()
@IsOptional()
@AssertOrWarn(
(env, value) =>
!env.AUTH_SSO_ENABLED ||
(env.AUTH_SSO_ENABLED &&
value !== 'replace_me_with_a_random_string_session'),
{
message:
'SESSION_STORE_SECRET should be changed to a secure, random string.',
},
)
SESSION_STORE_SECRET = 'replace_me_with_a_random_string_session';
@CastToBoolean()

View File

@ -7,7 +7,6 @@ export enum FeatureFlagKey {
IsFreeAccessEnabled = 'IS_FREE_ACCESS_ENABLED',
IsFunctionSettingsEnabled = 'IS_FUNCTION_SETTINGS_ENABLED',
IsWorkflowEnabled = 'IS_WORKFLOW_ENABLED',
IsSSOEnabled = 'IS_SSO_ENABLED',
IsGmailSendEmailScopeEnabled = 'IS_GMAIL_SEND_EMAIL_SCOPE_ENABLED',
IsAnalyticsV2Enabled = 'IS_ANALYTICS_V2_ENABLED',
IsUniqueIndexesEnabled = 'IS_UNIQUE_INDEXES_ENABLED',

View File

@ -9,8 +9,6 @@ import { Repository } from 'typeorm';
import { BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum';
import { BillingService } from 'src/engine/core-modules/billing/services/billing.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import {
SSOException,
SSOExceptionCode,
@ -30,8 +28,6 @@ import {
export class SSOService {
private readonly featureLookUpKey = BillingEntitlementKey.SSO;
constructor(
@InjectRepository(FeatureFlagEntity, 'core')
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
@InjectRepository(WorkspaceSSOIdentityProvider, 'core')
private readonly workspaceSSOIdentityProviderRepository: Repository<WorkspaceSSOIdentityProvider>,
private readonly environmentService: EnvironmentService,
@ -39,18 +35,6 @@ export class SSOService {
) {}
private async isSSOEnabled(workspaceId: string) {
const isSSOEnabledFeatureFlag = await this.featureFlagRepository.findOneBy({
workspaceId,
key: FeatureFlagKey.IsSSOEnabled,
value: true,
});
if (!isSSOEnabledFeatureFlag?.value) {
throw new SSOException(
`${FeatureFlagKey.IsSSOEnabled} feature flag is disabled`,
SSOExceptionCode.SSO_DISABLE,
);
}
const isSSOBillingEnabled =
await this.billingService.hasWorkspaceActiveSubscriptionOrFreeAccessOrEntitlement(
workspaceId,
@ -59,7 +43,7 @@ export class SSOService {
if (!isSSOBillingEnabled) {
throw new SSOException(
`${FeatureFlagKey.IsSSOEnabled} feature is enabled but no entitlement for this workspace`,
`No entitlement found for this workspace`,
SSOExceptionCode.SSO_DISABLE,
);
}

View File

@ -84,9 +84,7 @@ const bootstrap = async () => {
generateFrontConfig();
// Enable session - Today it's used only for SSO
if (environmentService.get('AUTH_SSO_ENABLED')) {
app.use(session(getSessionStorageOptions(environmentService)));
}
app.use(session(getSessionStorageOptions(environmentService)));
await app.listen(environmentService.get('PORT'));
};

View File

@ -116,7 +116,6 @@ yarn command:prod cron:calendar:ongoing-stale
['AUTH_GOOGLE_CLIENT_SECRET', '', 'Google client secret'],
['AUTH_GOOGLE_CALLBACK_URL', 'https://[YourDomain]/auth/google/redirect', 'Google auth callback'],
['AUTH_MICROSOFT_ENABLED', 'false', 'Enable Microsoft SSO login'],
['AUTH_SSO_ENABLED', 'false', 'Enable SSO with SAML or OIDC'],
['AUTH_MICROSOFT_CLIENT_ID', '', 'Microsoft client ID'],
['AUTH_MICROSOFT_TENANT_ID', '', 'Microsoft tenant ID'],
['AUTH_MICROSOFT_CLIENT_SECRET', '', 'Microsoft client secret'],