Skip to content

Commit 8a28d1f

Browse files
authoredNov 28, 2024··
feat(types,clerkjs,backend): Add support for enterprise_sso strategy (#4596)
1 parent c02e208 commit 8a28d1f

25 files changed

+194
-48
lines changed
 

‎.changeset/clever-cougars-argue.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
'@clerk/clerk-js': minor
3+
---
4+
5+
- Update the supported API version to `2024-10-01` that includes the following changes
6+
- Notification for new sign ins to users' accounts feature becomes available.
7+
- The response for Sign Ins with an email address that matches a **SAML connection** is updated. Instead of responding with a status of `needs_identifier` the API will now return a status of `needs_first_factor` and the email address that matched will be returned in the identifier field. the only strategy that will be included in supported first factors is `enterprise_sso`
8+
9+
Read more in the [API Version docs](https://clerk.com/docs/backend-requests/versioning/available-versions#2024-10-01)
10+
11+
- Update components to use the new `enterprise_sso` strategy for sign ins / sign ups that match an enterprise connection and handle the new API response.
12+
13+
This strategy supersedes SAML to provide a single strategy as the entry point for Enterprise SSO regardless of the underlying protocol used to authenticate the user.
14+
15+
For now there are two new types of connections that are supported in addition to SAML, Custom OAuth and EASIE (multi-tenant OAuth).

‎.changeset/famous-experts-begin.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
'@clerk/types': patch
3+
---
4+
5+
Add support for the new `enterprise_sso` strategy.
6+
7+
This strategy supersedes SAML to provide a single strategy as the entry point for Enterprise Single Sign On regardless of the underlying protocol used to authenticate the user.
8+
For now there are two new types of connections that are supported in addition to SAML, Custom OAuth and EASIE (multi-tenant OAuth).
9+
10+
- Add a new user setting `enterpriseSSO`, this gets enabled when there is an active enterprise connection for an instance.
11+
- Add support for signing in / signing up with the new `enterprise_sso` strategy.
12+
- Deprecated `userSettings.saml` in favor of `enterprise_sso`.
13+
- Deprecated `saml` sign in strategy in favor of `enterprise_sso`.

‎.changeset/short-mails-wash.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@clerk/backend': patch
3+
---
4+
5+
Update the supported API version to `2024-10-01` that includes the following changes
6+
7+
No changes affecting the Backend API have been made in this version.
8+
9+
Read more in the [API Version docs](https://clerk.com/docs/backend-requests/versioning/available-versions#2024-10-01)

‎packages/backend/src/constants.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export const API_VERSION = 'v1';
44
export const USER_AGENT = `${PACKAGE_NAME}@${PACKAGE_VERSION}`;
55
export const MAX_CACHE_LAST_UPDATED_AT_SECONDS = 5 * 60;
66
export const JWKS_CACHE_TTL_MS = 1000 * 60 * 60;
7-
export const SUPPORTED_BAPI_VERSION = '2021-02-05';
7+
export const SUPPORTED_BAPI_VERSION = '2024-10-01';
88

99
const Attributes = {
1010
AuthToken: '__clerkAuthToken',

‎packages/clerk-js/src/core/clerk.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1382,7 +1382,8 @@ export class Clerk implements ClerkInterface {
13821382
return navigateToSignIn();
13831383
}
13841384

1385-
const userHasUnverifiedEmail = si.status === 'needs_first_factor';
1385+
const userHasUnverifiedEmail =
1386+
si.status === 'needs_first_factor' && !signIn.supportedFirstFactors?.every(f => f.strategy === 'enterprise_sso');
13861387

13871388
if (userHasUnverifiedEmail) {
13881389
return navigateToFactorOne();

‎packages/clerk-js/src/core/constants.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ export const SIGN_UP_MODES: Record<string, SignUpModes> = {
4646
};
4747

4848
// This is the currently supported version of the Frontend API
49-
export const SUPPORTED_FAPI_VERSION = '2021-02-05';
49+
export const SUPPORTED_FAPI_VERSION = '2024-10-01';

‎packages/clerk-js/src/core/resources/SignIn.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
CreateEmailLinkFlowReturn,
1515
EmailCodeConfig,
1616
EmailLinkConfig,
17+
EnterpriseSSOConfig,
1718
PassKeyConfig,
1819
PasskeyFactor,
1920
PhoneCodeConfig,
@@ -134,6 +135,12 @@ export class SignIn extends BaseResource implements SignInResource {
134135
actionCompleteRedirectUrl: factor.actionCompleteRedirectUrl,
135136
} as SamlConfig;
136137
break;
138+
case 'enterprise_sso':
139+
config = {
140+
redirectUrl: factor.redirectUrl,
141+
actionCompleteRedirectUrl: factor.actionCompleteRedirectUrl,
142+
} as EnterpriseSSOConfig;
143+
break;
137144
default:
138145
clerkInvalidStrategy('SignIn.prepareFirstFactor', factor.strategy);
139146
}
@@ -215,7 +222,7 @@ export class SignIn extends BaseResource implements SignInResource {
215222
const { strategy, redirectUrl, redirectUrlComplete, identifier } = params || {};
216223

217224
const { firstFactorVerification } =
218-
strategy === 'saml' && this.id
225+
(strategy === 'saml' || strategy === 'enterprise_sso') && this.id
219226
? await this.prepareFirstFactor({
220227
strategy,
221228
redirectUrl: SignIn.clerk.buildUrlWithAuth(redirectUrl),

‎packages/clerk-js/src/core/resources/UserSettings.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type {
22
Attributes,
3+
EnterpriseSSOSettings,
34
OAuthProviders,
45
OAuthStrategy,
56
PasskeySettingsData,
@@ -30,6 +31,7 @@ export class UserSettings extends BaseResource implements UserSettingsResource {
3031
social!: OAuthProviders;
3132

3233
saml!: SamlSettings;
34+
enterpriseSSO!: EnterpriseSSOSettings;
3335

3436
attributes!: Attributes;
3537
actions!: Actions;
@@ -67,6 +69,7 @@ export class UserSettings extends BaseResource implements UserSettingsResource {
6769

6870
this.social = data.social;
6971
this.saml = data.saml;
72+
this.enterpriseSSO = data.enterprise_sso;
7073
this.attributes = Object.fromEntries(
7174
Object.entries(data.attributes).map(a => [a[0], { ...a[1], name: a[0] }]),
7275
) as Attributes;

‎packages/clerk-js/src/ui/components/SignIn/SignInStart.tsx

+20-13
Original file line numberDiff line numberDiff line change
@@ -245,31 +245,34 @@ export function _SignInStart(): JSX.Element {
245245
const hasPassword = fields.some(f => f.name === 'password' && !!f.value);
246246

247247
/**
248-
* FAPI will return an error when password is submitted but the user's email matches requires SAML authentication.
248+
* FAPI will return an error when password is submitted but the user's email matches requires enterprise sso authentication.
249249
* We need to strip password from the create request, and reconstruct it later.
250250
*/
251-
if (!hasPassword || userSettings.saml.enabled) {
251+
if (!hasPassword || userSettings.enterpriseSSO.enabled) {
252252
fields = fields.filter(f => f.name !== 'password');
253253
}
254254
return {
255255
...buildRequest(fields),
256-
...(hasPassword && !userSettings.saml.enabled && { strategy: 'password' }),
256+
...(hasPassword && !userSettings.enterpriseSSO.enabled && { strategy: 'password' }),
257257
} as SignInCreateParams;
258258
};
259259

260-
const safePasswordSignInForSamlInstance = (
260+
const safePasswordSignInForEnterpriseSSOInstance = (
261261
signInCreatePromise: Promise<SignInResource>,
262262
fields: Array<FormControlState<string>>,
263263
) => {
264264
return signInCreatePromise.then(signInResource => {
265-
if (!userSettings.saml.enabled) {
265+
if (!userSettings.enterpriseSSO.enabled) {
266266
return signInResource;
267267
}
268268
/**
269-
* For SAML enabled instances, perform sign in with password only when it is allowed for the identified user.
269+
* For instances with Enterprise SSO enabled, perform sign in with password only when it is allowed for the identified user.
270270
*/
271271
const passwordField = fields.find(f => f.name === 'password')?.value;
272-
if (!passwordField || signInResource.supportedFirstFactors?.some(ff => ff.strategy === 'saml')) {
272+
if (
273+
!passwordField ||
274+
signInResource.supportedFirstFactors?.some(ff => ff.strategy === 'saml' || ff.strategy === 'enterprise_sso')
275+
) {
273276
return signInResource;
274277
}
275278
return signInResource.attemptFirstFactor({ strategy: 'password', password: passwordField });
@@ -278,16 +281,20 @@ export function _SignInStart(): JSX.Element {
278281

279282
const signInWithFields = async (...fields: Array<FormControlState<string>>) => {
280283
try {
281-
const res = await safePasswordSignInForSamlInstance(signIn.create(buildSignInParams(fields)), fields);
284+
const res = await safePasswordSignInForEnterpriseSSOInstance(signIn.create(buildSignInParams(fields)), fields);
282285

283286
switch (res.status) {
284287
case 'needs_identifier':
285-
// Check if we need to initiate a saml flow
286-
if (res.supportedFirstFactors?.some(ff => ff.strategy === 'saml')) {
287-
await authenticateWithSaml();
288+
// Check if we need to initiate an enterprise sso flow
289+
if (res.supportedFirstFactors?.some(ff => ff.strategy === 'saml' || ff.strategy === 'enterprise_sso')) {
290+
await authenticateWithEnterpriseSSO();
288291
}
289292
break;
290293
case 'needs_first_factor':
294+
if (res.supportedFirstFactors?.every(ff => ff.strategy === 'enterprise_sso')) {
295+
await authenticateWithEnterpriseSSO();
296+
break;
297+
}
291298
return navigate('factor-one');
292299
case 'needs_second_factor':
293300
return navigate('factor-two');
@@ -306,12 +313,12 @@ export function _SignInStart(): JSX.Element {
306313
}
307314
};
308315

309-
const authenticateWithSaml = async () => {
316+
const authenticateWithEnterpriseSSO = async () => {
310317
const redirectUrl = buildSSOCallbackURL(ctx, displayConfig.signInUrl);
311318
const redirectUrlComplete = ctx.afterSignInUrl || '/';
312319

313320
return signIn.authenticateWithRedirect({
314-
strategy: 'saml',
321+
strategy: 'enterprise_sso',
315322
redirectUrl,
316323
redirectUrlComplete,
317324
});

‎packages/clerk-js/src/ui/components/SignIn/__tests__/SignInStart.test.tsx

+24-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,30 @@ describe('SignInStart', () => {
286286
await userEvent.click(screen.getByText('Continue'));
287287
expect(fixtures.signIn.create).toHaveBeenCalled();
288288
expect(fixtures.signIn.authenticateWithRedirect).toHaveBeenCalledWith({
289-
strategy: 'saml',
289+
strategy: 'enterprise_sso',
290+
redirectUrl: 'http://localhost/#/sso-callback',
291+
redirectUrlComplete: '/',
292+
});
293+
});
294+
});
295+
296+
describe('Enterprise SSO', () => {
297+
it('initiates a Enterprise SSO flow if enterprise_sso is listed as the only supported first factor', async () => {
298+
const { wrapper, fixtures } = await createFixtures(f => {
299+
f.withEmailAddress();
300+
});
301+
fixtures.signIn.create.mockReturnValueOnce(
302+
Promise.resolve({
303+
status: 'needs_first_factor',
304+
supportedFirstFactors: [{ strategy: 'enterprise_sso' }],
305+
} as unknown as SignInResource),
306+
);
307+
const { userEvent } = render(<SignInStart />, { wrapper });
308+
await userEvent.type(screen.getByLabelText(/email address/i), 'hello@clerk.com');
309+
await userEvent.click(screen.getByText('Continue'));
310+
expect(fixtures.signIn.create).toHaveBeenCalled();
311+
expect(fixtures.signIn.authenticateWithRedirect).toHaveBeenCalledWith({
312+
strategy: 'enterprise_sso',
290313
redirectUrl: 'http://localhost/#/sso-callback',
291314
redirectUrlComplete: '/',
292315
});

‎packages/clerk-js/src/ui/components/UserProfile/AccountPage.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ import { UserProfileSection } from './UserProfileSection';
1212
import { Web3Section } from './Web3Section';
1313

1414
export const AccountPage = withCardStateProvider(() => {
15-
const { attributes, social } = useEnvironment().userSettings;
15+
const { attributes, social, enterpriseSSO } = useEnvironment().userSettings;
1616
const card = useCardState();
1717
const { user } = useUser();
1818

1919
const showUsername = attributes.username.enabled;
2020
const showEmail = attributes.email_address.enabled;
2121
const showPhone = attributes.phone_number.enabled;
2222
const showConnectedAccounts = social && Object.values(social).filter(p => p.enabled).length > 0;
23-
const showEnterpriseAccounts = user && user.enterpriseAccounts.length > 0;
23+
const showEnterpriseAccounts = user && enterpriseSSO.enabled;
2424
const showWeb3 = attributes.web3_wallet.enabled;
2525

2626
const shouldAllowIdentificationCreation =

‎packages/clerk-js/src/ui/components/UserProfile/__tests__/AccountPage.test.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ describe('AccountPage', () => {
9191

9292
const { wrapper } = await createFixtures(f => {
9393
f.withEmailAddress();
94-
f.withSaml();
94+
f.withEnterpriseSso();
9595
f.withUser({
9696
email_addresses: [emailAddress],
9797
enterprise_accounts: [
@@ -157,6 +157,7 @@ describe('AccountPage', () => {
157157

158158
const { wrapper } = await createFixtures(f => {
159159
f.withEmailAddress();
160+
f.withEnterpriseSso();
160161
f.withUser({
161162
email_addresses: [emailAddress],
162163
enterprise_accounts: [
@@ -268,7 +269,7 @@ describe('AccountPage', () => {
268269
f.withEmailAddress();
269270
f.withPhoneNumber();
270271
f.withSocialProvider({ provider: 'google' });
271-
f.withSaml();
272+
f.withEnterpriseSso();
272273
f.withUser({
273274
email_addresses: [emailAddress],
274275
enterprise_accounts: [enterpriseAccount],
@@ -291,7 +292,7 @@ describe('AccountPage', () => {
291292
f.withEmailAddress();
292293
f.withPhoneNumber();
293294
f.withSocialProvider({ provider: 'google' });
294-
f.withSaml();
295+
f.withEnterpriseSso();
295296
f.withUser({
296297
email_addresses: [emailAddress],
297298
phone_numbers: [phoneNumber],

‎packages/clerk-js/src/ui/components/UserProfile/__tests__/EnterpriseAccountsSection.test.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const withoutEnterpriseConnection = createFixtures.config(f => {
1818
const withInactiveEnterpriseConnection = createFixtures.config(f => {
1919
f.withSocialProvider({ provider: 'google' });
2020
f.withSocialProvider({ provider: 'github' });
21+
f.withEnterpriseSso();
2122
f.withUser({
2223
enterprise_accounts: [
2324
{
@@ -67,6 +68,7 @@ const withInactiveEnterpriseConnection = createFixtures.config(f => {
6768
});
6869

6970
const withOAuthBuiltInEnterpriseConnection = createFixtures.config(f => {
71+
f.withEnterpriseSso();
7072
f.withUser({
7173
enterprise_accounts: [
7274
{
@@ -117,6 +119,7 @@ const withOAuthBuiltInEnterpriseConnection = createFixtures.config(f => {
117119

118120
const withOAuthCustomEnterpriseConnection = (logoPublicUrl: string | null) =>
119121
createFixtures.config(f => {
122+
f.withEnterpriseSso();
120123
f.withUser({
121124
enterprise_accounts: [
122125
{
@@ -166,6 +169,7 @@ const withOAuthCustomEnterpriseConnection = (logoPublicUrl: string | null) =>
166169
});
167170

168171
const withSamlEnterpriseConnection = createFixtures.config(f => {
172+
f.withEnterpriseSso();
169173
f.withUser({
170174
enterprise_accounts: [
171175
{

‎packages/clerk-js/src/ui/components/UserProfile/__tests__/PasswordSection.test.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ describe('PasswordSection', () => {
106106
});
107107
});
108108

109-
describe('with SAML', () => {
109+
describe('with Enterprise SSO', () => {
110110
it('prevents setting a password if user has active enterprise connections', async () => {
111111
const emailAddress = 'george@jungle.com';
112112

113113
const config = createFixtures.config(f => {
114114
f.withEmailAddress();
115-
f.withSaml();
115+
f.withEnterpriseSso();
116116
f.withUser({
117117
email_addresses: [emailAddress],
118118
enterprise_accounts: [
@@ -185,7 +185,7 @@ describe('PasswordSection', () => {
185185

186186
const config = createFixtures.config(f => {
187187
f.withEmailAddress();
188-
f.withSaml();
188+
f.withEnterpriseSso();
189189
f.withUser({
190190
email_addresses: [emailAddress],
191191
enterprise_accounts: [
@@ -315,13 +315,13 @@ describe('PasswordSection', () => {
315315
expect(queryByRole('heading', { name: /update password/i })).not.toBeInTheDocument();
316316
});
317317

318-
describe('with SAML', () => {
318+
describe('with Enterprise SSO', () => {
319319
it('prevents changing a password if user has active enterprise connections', async () => {
320320
const emailAddress = 'george@jungle.com';
321321

322322
const config = createFixtures.config(f => {
323323
f.withEmailAddress();
324-
f.withSaml();
324+
f.withEnterpriseSso();
325325
f.withUser({
326326
password_enabled: true,
327327
email_addresses: [emailAddress],
@@ -395,7 +395,7 @@ describe('PasswordSection', () => {
395395

396396
const config = createFixtures.config(f => {
397397
f.withEmailAddress();
398-
f.withSaml();
398+
f.withEnterpriseSso();
399399
f.withUser({
400400
password_enabled: true,
401401
email_addresses: [emailAddress],

‎packages/clerk-js/src/ui/components/UserProfile/__tests__/UserProfileSection.test.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,15 @@ describe('ProfileSection', () => {
5151
});
5252
});
5353

54-
describe('with SAML', () => {
54+
describe('with Enterprise SSO', () => {
5555
it('disables the first & last name inputs if user has active enterprise connections', async () => {
5656
const emailAddress = 'george@jungle.com';
5757
const firstName = 'George';
5858
const lastName = 'Clerk';
5959

6060
const config = createFixtures.config(f => {
6161
f.withEmailAddress();
62-
f.withSaml();
62+
f.withEnterpriseSso();
6363
f.withName();
6464
f.withUser({
6565
first_name: firstName,
@@ -134,7 +134,7 @@ describe('ProfileSection', () => {
134134

135135
const config = createFixtures.config(f => {
136136
f.withEmailAddress();
137-
f.withSaml();
137+
f.withEnterpriseSso();
138138
f.withName();
139139
f.withUser({
140140
first_name: firstName,

‎packages/clerk-js/src/ui/utils/test/fixtureHelpers.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,9 @@ const createUserSettingsFixtureHelpers = (environment: EnvironmentJSON) => {
466466
};
467467
};
468468

469-
const withSaml = () => {
469+
const withEnterpriseSso = () => {
470470
us.saml = { enabled: true };
471+
us.enterprise_sso = { enabled: true };
471472
};
472473

473474
const withBackupCode = (opts?: Partial<UserSettingsJSON['attributes']['backup_code']>) => {
@@ -524,7 +525,7 @@ const createUserSettingsFixtureHelpers = (environment: EnvironmentJSON) => {
524525
withPassword,
525526
withPasswordComplexity,
526527
withSocialProvider,
527-
withSaml,
528+
withEnterpriseSso,
528529
withBackupCode,
529530
withAuthenticatorApp,
530531
withPasskey,

‎packages/clerk-js/src/ui/utils/test/fixtures.ts

+1
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ const createBaseUserSettings = (): UserSettingsJSON => {
179179
actions: { delete_self: false, create_organization: false },
180180
social: { ...socialConfig },
181181
saml: { enabled: false },
182+
enterprise_sso: { enabled: false },
182183
sign_in: {
183184
second_factor: {
184185
required: false,

‎packages/clerk-js/src/utils/__tests__/completeSignUpFlow.test.ts

+29-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,35 @@ describe('completeSignUpFlow', () => {
104104
expect(mockHandleComplete).not.toHaveBeenCalled();
105105
expect(mockNavigate).not.toHaveBeenCalled();
106106
expect(mockAuthenticateWithRedirect).toHaveBeenCalledWith({
107-
strategy: 'saml',
107+
strategy: 'enterprise_sso',
108+
redirectUrl,
109+
redirectUrlComplete,
110+
continueSignUp: true,
111+
});
112+
});
113+
114+
it('initiates a Enterprise SSO flow if enterprise_sso is listed as a missing field', async () => {
115+
const redirectUrl = 'https://www.in.gr/acs';
116+
const redirectUrlComplete = 'https://www.in.gr/tada';
117+
118+
const mockSignUp = {
119+
status: 'missing_requirements',
120+
missingFields: ['enterprise_sso'],
121+
authenticateWithRedirect: mockAuthenticateWithRedirect,
122+
} as unknown as SignUpResource;
123+
124+
await completeSignUpFlow({
125+
signUp: mockSignUp,
126+
handleComplete: mockHandleComplete,
127+
navigate: mockNavigate,
128+
redirectUrl: 'https://www.in.gr/acs',
129+
redirectUrlComplete: 'https://www.in.gr/tada',
130+
});
131+
132+
expect(mockHandleComplete).not.toHaveBeenCalled();
133+
expect(mockNavigate).not.toHaveBeenCalled();
134+
expect(mockAuthenticateWithRedirect).toHaveBeenCalledWith({
135+
strategy: 'enterprise_sso',
108136
redirectUrl,
109137
redirectUrlComplete,
110138
continueSignUp: true,

‎packages/clerk-js/src/utils/completeSignUpFlow.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ export const completeSignUpFlow = ({
2222
if (signUp.status === 'complete') {
2323
return handleComplete && handleComplete();
2424
} else if (signUp.status === 'missing_requirements') {
25-
if (signUp.missingFields.some(mf => mf === 'saml')) {
25+
if (signUp.missingFields.some(mf => mf === 'saml' || mf === 'enterprise_sso')) {
2626
return signUp.authenticateWithRedirect({
27-
strategy: 'saml',
27+
strategy: 'enterprise_sso',
2828
redirectUrl,
2929
redirectUrlComplete,
3030
continueSignUp: true,

‎packages/types/src/factors.ts

+10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
BackupCodeStrategy,
44
EmailCodeStrategy,
55
EmailLinkStrategy,
6+
EnterpriseSSOStrategy,
67
OAuthStrategy,
78
PasskeyStrategy,
89
PasswordStrategy,
@@ -58,6 +59,10 @@ export type SamlFactor = {
5859
strategy: SamlStrategy;
5960
};
6061

62+
export type EnterpriseSSOFactor = {
63+
strategy: EnterpriseSSOStrategy;
64+
};
65+
6166
export type TOTPFactor = {
6267
strategy: TOTPStrategy;
6368
};
@@ -103,6 +108,11 @@ export type SamlConfig = SamlFactor & {
103108
actionCompleteRedirectUrl: string;
104109
};
105110

111+
export type EnterpriseSSOConfig = EnterpriseSSOFactor & {
112+
redirectUrl: string;
113+
actionCompleteRedirectUrl: string;
114+
};
115+
106116
export type PhoneCodeSecondFactorConfig = {
107117
strategy: PhoneCodeStrategy;
108118
phoneNumberId?: string;

‎packages/types/src/redirects.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { OAuthStrategy, SamlStrategy } from './strategies';
1+
import type { EnterpriseSSOStrategy, OAuthStrategy, SamlStrategy } from './strategies';
22

33
export type AfterSignOutUrl = {
44
/**
@@ -66,17 +66,17 @@ export type AuthenticateWithRedirectParams = {
6666

6767
/**
6868
* One of the supported OAuth providers you can use to authenticate with, eg 'oauth_google'.
69-
* Or alternatively `saml`, to authenticate with SAML.
69+
* Alternatively `saml` or `enterprise_sso`, to authenticate with Enterprise SSO.
7070
*/
71-
strategy: OAuthStrategy | SamlStrategy;
71+
strategy: OAuthStrategy | SamlStrategy | EnterpriseSSOStrategy;
7272

7373
/**
74-
* Identifier to use for targeting a SAML connection at sign-in
74+
* Identifier to use for targeting a Enterprise Connection at sign-in
7575
*/
7676
identifier?: string;
7777

7878
/**
79-
* Email address to use for targeting a SAML connection at sign-up
79+
* Email address to use for targeting a Enterprise Connection at sign-up
8080
*/
8181
emailAddress?: string;
8282

‎packages/types/src/signIn.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import type {
66
EmailCodeFactor,
77
EmailLinkConfig,
88
EmailLinkFactor,
9+
EnterpriseSSOConfig,
10+
EnterpriseSSOFactor,
911
OAuthConfig,
1012
OauthFactor,
1113
PasskeyAttempt,
@@ -51,6 +53,7 @@ import type {
5153
BackupCodeStrategy,
5254
EmailCodeStrategy,
5355
EmailLinkStrategy,
56+
EnterpriseSSOStrategy,
5457
GoogleOneTapStrategy,
5558
OAuthStrategy,
5659
PasskeyStrategy,
@@ -130,7 +133,8 @@ export type SignInFirstFactor =
130133
| ResetPasswordEmailCodeFactor
131134
| Web3SignatureFactor
132135
| OauthFactor
133-
| SamlFactor;
136+
| SamlFactor
137+
| EnterpriseSSOFactor;
134138

135139
export type SignInSecondFactor = PhoneCodeFactor | TOTPFactor | BackupCodeFactor;
136140

@@ -152,7 +156,8 @@ export type PrepareFirstFactorParams =
152156
| ResetPasswordPhoneCodeFactorConfig
153157
| ResetPasswordEmailCodeFactorConfig
154158
| OAuthConfig
155-
| SamlConfig;
159+
| SamlConfig
160+
| EnterpriseSSOConfig;
156161

157162
export type AttemptFirstFactorParams =
158163
| PasskeyAttempt
@@ -169,7 +174,7 @@ export type AttemptSecondFactorParams = PhoneCodeAttempt | TOTPAttempt | BackupC
169174

170175
export type SignInCreateParams = (
171176
| {
172-
strategy: OAuthStrategy | SamlStrategy;
177+
strategy: OAuthStrategy | SamlStrategy | EnterpriseSSOStrategy;
173178
redirectUrl: string;
174179
actionCompleteRedirectUrl?: string;
175180
identifier?: string;
@@ -234,7 +239,8 @@ export type SignInStrategy =
234239
| TOTPStrategy
235240
| BackupCodeStrategy
236241
| OAuthStrategy
237-
| SamlStrategy;
242+
| SamlStrategy
243+
| EnterpriseSSOStrategy;
238244

239245
export interface SignInJSON extends ClerkResourceJSON {
240246
object: 'sign_in';

‎packages/types/src/signUp.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type { ClerkResource } from './resource';
1414
import type {
1515
EmailCodeStrategy,
1616
EmailLinkStrategy,
17+
EnterpriseSSOStrategy,
1718
GoogleOneTapStrategy,
1819
OAuthStrategy,
1920
PhoneCodeStrategy,
@@ -150,15 +151,15 @@ export type SignUpVerifiableField =
150151
| Web3WalletIdentifier;
151152

152153
// TODO: Does it make sense that the identification *field* holds a *strategy*?
153-
export type SignUpIdentificationField = SignUpVerifiableField | OAuthStrategy | SamlStrategy;
154+
export type SignUpIdentificationField = SignUpVerifiableField | OAuthStrategy | SamlStrategy | EnterpriseSSOStrategy;
154155

155156
// TODO: Replace with discriminated union type
156157
export type SignUpCreateParams = Partial<
157158
{
158159
externalAccountStrategy: string;
159160
externalAccountRedirectUrl: string;
160161
externalAccountActionCompleteRedirectUrl: string;
161-
strategy: OAuthStrategy | SamlStrategy | TicketStrategy | GoogleOneTapStrategy;
162+
strategy: OAuthStrategy | SamlStrategy | EnterpriseSSOStrategy | TicketStrategy | GoogleOneTapStrategy;
162163
redirectUrl: string;
163164
actionCompleteRedirectUrl: string;
164165
transfer: boolean;

‎packages/types/src/strategies.ts

+4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ export type BackupCodeStrategy = 'backup_code';
1313
export type ResetPasswordPhoneCodeStrategy = 'reset_password_phone_code';
1414
export type ResetPasswordEmailCodeStrategy = 'reset_password_email_code';
1515
export type CustomOAuthStrategy = `oauth_custom_${string}`;
16+
export type EnterpriseSSOStrategy = 'enterprise_sso';
1617

1718
export type OAuthStrategy = `oauth_${OAuthProvider}` | CustomOAuthStrategy;
1819
export type Web3Strategy = `web3_${Web3Provider}_signature`;
1920

21+
/**
22+
* @deprecated Use `EnterpriseSSOStrategy` instead
23+
*/
2024
export type SamlStrategy = 'saml';

‎packages/types/src/userSettings.ts

+12
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ export type SamlSettings = {
8383
enabled: boolean;
8484
};
8585

86+
export type EnterpriseSSOSettings = {
87+
enabled: boolean;
88+
};
89+
8690
export type AttributesJSON = {
8791
[attribute in Attribute]: AttributeDataJSON;
8892
};
@@ -103,7 +107,11 @@ export interface UserSettingsJSON extends ClerkResourceJSON {
103107
actions: Actions;
104108
social: OAuthProviders;
105109

110+
/**
111+
* @deprecated Use `enterprise_sso` instead
112+
*/
106113
saml: SamlSettings;
114+
enterprise_sso: EnterpriseSSOSettings;
107115

108116
sign_in: SignInData;
109117
sign_up: SignUpData;
@@ -115,7 +123,11 @@ export interface UserSettingsResource extends ClerkResource {
115123
id?: undefined;
116124
social: OAuthProviders;
117125

126+
/**
127+
* @deprecated Use `enterprise_sso` instead
128+
*/
118129
saml: SamlSettings;
130+
enterpriseSSO: EnterpriseSSOSettings;
119131

120132
attributes: Attributes;
121133
actions: Actions;

0 commit comments

Comments
 (0)
Please sign in to comment.