Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/salty-maps-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@clerk/clerk-js': major
'@clerk/shared': major
'@clerk/ui': major
---

Remove deprecated `saml` strategy in favor of `enterprise_sso`
9 changes: 1 addition & 8 deletions packages/clerk-js/src/core/resources/SignIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import type {
ResetPasswordEmailCodeFactorConfig,
ResetPasswordParams,
ResetPasswordPhoneCodeFactorConfig,
SamlConfig,
SignInCreateParams,
SignInFirstFactor,
SignInFutureBackupCodeVerifyParams,
Expand Down Expand Up @@ -211,12 +210,6 @@ export class SignIn extends BaseResource implements SignInResource {
case 'reset_password_email_code':
config = { emailAddressId: params.emailAddressId } as ResetPasswordEmailCodeFactorConfig;
break;
case 'saml':
config = {
redirectUrl: params.redirectUrl,
actionCompleteRedirectUrl: params.actionCompleteRedirectUrl,
} as SamlConfig;
break;
case 'enterprise_sso':
config = {
redirectUrl: params.redirectUrl,
Expand Down Expand Up @@ -336,7 +329,7 @@ export class SignIn extends BaseResource implements SignInResource {
});
}

if (strategy === 'saml' || strategy === 'enterprise_sso') {
if (strategy === 'enterprise_sso') {
await this.prepareFirstFactor({
strategy,
redirectUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,34 +85,6 @@ describe('completeSignUpFlow', () => {
expect(mockNavigate).not.toHaveBeenCalled();
});

it('initiates a SAML flow if saml is listed as a missing field', async () => {
const redirectUrl = 'https://www.in.gr/acs';
const redirectUrlComplete = 'https://www.in.gr/tada';

const mockSignUp = {
status: 'missing_requirements',
missingFields: ['saml'],
authenticateWithRedirect: mockAuthenticateWithRedirect,
} as unknown as SignUpResource;

await completeSignUpFlow({
signUp: mockSignUp,
handleComplete: mockHandleComplete,
navigate: mockNavigate,
redirectUrl: 'https://www.in.gr/acs',
redirectUrlComplete: 'https://www.in.gr/tada',
});

expect(mockHandleComplete).not.toHaveBeenCalled();
expect(mockNavigate).not.toHaveBeenCalled();
expect(mockAuthenticateWithRedirect).toHaveBeenCalledWith({
strategy: 'enterprise_sso',
redirectUrl,
redirectUrlComplete,
continueSignUp: true,
});
});

it('initiates a Enterprise SSO flow if enterprise_sso is listed as a missing field', async () => {
const redirectUrl = 'https://www.in.gr/acs';
const redirectUrlComplete = 'https://www.in.gr/tada';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const completeSignUpFlow = ({
if (signUp.status === 'complete') {
return handleComplete && handleComplete();
} else if (signUp.status === 'missing_requirements') {
if (signUp.missingFields.some(mf => mf === 'saml' || mf === 'enterprise_sso')) {
if (signUp.missingFields.some(mf => mf === 'enterprise_sso')) {
return signUp.authenticateWithRedirect({
strategy: 'enterprise_sso',
redirectUrl,
Expand Down
10 changes: 0 additions & 10 deletions packages/shared/src/types/factors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import type {
PhoneCodeStrategy,
ResetPasswordEmailCodeStrategy,
ResetPasswordPhoneCodeStrategy,
SamlStrategy,
TOTPStrategy,
Web3Strategy,
} from './strategies';
Expand Down Expand Up @@ -57,10 +56,6 @@ export type OauthFactor = {
strategy: OAuthStrategy;
};

export type SamlFactor = {
strategy: SamlStrategy;
};

export type EnterpriseSSOFactor = {
strategy: EnterpriseSSOStrategy;
/**
Expand Down Expand Up @@ -115,11 +110,6 @@ export type OAuthConfig = OauthFactor & {
oidcLoginHint?: string;
};

export type SamlConfig = SamlFactor & {
redirectUrl: string;
actionCompleteRedirectUrl: string;
};

export type EnterpriseSSOConfig = EnterpriseSSOFactor & {
redirectUrl: string;
actionCompleteRedirectUrl: string;
Expand Down
6 changes: 3 additions & 3 deletions packages/shared/src/types/redirects.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { EnterpriseSSOStrategy, OAuthStrategy, SamlStrategy } from './strategies';
import type { EnterpriseSSOStrategy, OAuthStrategy } from './strategies';

export type AfterSignOutUrl = {
/**
Expand Down Expand Up @@ -50,9 +50,9 @@ export type AuthenticateWithRedirectParams = {

/**
* One of the supported OAuth providers you can use to authenticate with, eg 'oauth_google'.
* Alternatively `saml` or `enterprise_sso`, to authenticate with Enterprise SSO.
* Alternatively `enterprise_sso`, to authenticate with Enterprise SSO.
*/
strategy: OAuthStrategy | SamlStrategy | EnterpriseSSOStrategy;
strategy: OAuthStrategy | EnterpriseSSOStrategy;

/**
* Identifier to use for targeting a Enterprise Connection at sign-in
Expand Down
8 changes: 1 addition & 7 deletions packages/shared/src/types/signInCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import type {
ResetPasswordPhoneCodeAttempt,
ResetPasswordPhoneCodeFactor,
ResetPasswordPhoneCodeFactorConfig,
SamlConfig,
SamlFactor,
TOTPAttempt,
TOTPFactor,
Web3Attempt,
Expand All @@ -53,7 +51,6 @@ import type {
PhoneCodeStrategy,
ResetPasswordEmailCodeStrategy,
ResetPasswordPhoneCodeStrategy,
SamlStrategy,
TicketStrategy,
TOTPStrategy,
Web3Strategy,
Expand Down Expand Up @@ -83,7 +80,6 @@ export type SignInFirstFactor =
| ResetPasswordEmailCodeFactor
| Web3SignatureFactor
| OauthFactor
| SamlFactor
| EnterpriseSSOFactor;

export type SignInSecondFactor = PhoneCodeFactor | TOTPFactor | BackupCodeFactor | EmailCodeFactor | EmailLinkFactor;
Expand All @@ -106,7 +102,6 @@ export type PrepareFirstFactorParams =
| ResetPasswordPhoneCodeFactorConfig
| ResetPasswordEmailCodeFactorConfig
| OAuthConfig
| SamlConfig
| EnterpriseSSOConfig;

export type AttemptFirstFactorParams =
Expand All @@ -124,7 +119,7 @@ export type AttemptSecondFactorParams = PhoneCodeAttempt | TOTPAttempt | BackupC

export type SignInCreateParams = (
| {
strategy: OAuthStrategy | SamlStrategy | EnterpriseSSOStrategy;
strategy: OAuthStrategy | EnterpriseSSOStrategy;
redirectUrl: string;
actionCompleteRedirectUrl?: string;
identifier?: string;
Expand Down Expand Up @@ -195,5 +190,4 @@ export type SignInStrategy =
| TOTPStrategy
| BackupCodeStrategy
| OAuthStrategy
| SamlStrategy
| EnterpriseSSOStrategy;
2 changes: 1 addition & 1 deletion packages/shared/src/types/signInFuture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface SignInFutureCreateParams {
* The first factor verification strategy to use in the sign-in flow. Depends on the `identifier` value. Each
* authentication identifier supports different verification strategies.
*/
strategy?: OAuthStrategy | 'saml' | 'enterprise_sso' | PasskeyStrategy;
strategy?: OAuthStrategy | 'enterprise_sso' | PasskeyStrategy;
/**
* The full URL or path that the OAuth provider should redirect to after successful authorization on their part.
*/
Expand Down
6 changes: 2 additions & 4 deletions packages/shared/src/types/signUpCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import type {
GoogleOneTapStrategy,
OAuthStrategy,
PhoneCodeStrategy,
SamlStrategy,
TicketStrategy,
Web3Strategy,
} from './strategies';
Expand Down Expand Up @@ -50,7 +49,7 @@ export type PrepareVerificationParams =
oidcLoginHint?: string;
}
| {
strategy: SamlStrategy | EnterpriseSSOStrategy;
strategy: EnterpriseSSOStrategy;
redirectUrl?: string;
actionCompleteRedirectUrl?: string;
};
Expand All @@ -76,7 +75,7 @@ export type SignUpVerifiableField =
| Web3WalletIdentifier;

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

// TODO: Replace with discriminated union type
export type SignUpCreateParams = Partial<
Expand All @@ -86,7 +85,6 @@ export type SignUpCreateParams = Partial<
externalAccountActionCompleteRedirectUrl: string;
strategy:
| OAuthStrategy
| SamlStrategy
| EnterpriseSSOStrategy
| TicketStrategy
| GoogleOneTapStrategy
Expand Down
5 changes: 0 additions & 5 deletions packages/shared/src/types/strategies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,3 @@ export type EnterpriseSSOStrategy = 'enterprise_sso';

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

/**
* @deprecated Use `EnterpriseSSOStrategy` instead.
*/
export type SamlStrategy = 'saml';
7 changes: 2 additions & 5 deletions packages/ui/src/components/SignIn/SignInStart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,7 @@ function SignInStartInternal(): JSX.Element {
* For instances with Enterprise SSO enabled, perform sign in with password only when it is allowed for the identified user.
*/
const passwordField = fields.find(f => f.name === 'password')?.value;
if (
!passwordField ||
signInResource.supportedFirstFactors?.some(ff => ff.strategy === 'saml' || ff.strategy === 'enterprise_sso')
) {
if (!passwordField || signInResource.supportedFirstFactors?.some(ff => ff.strategy === 'enterprise_sso')) {
return signInResource;
}
return signInResource.attemptFirstFactor({ strategy: 'password', password: passwordField });
Expand Down Expand Up @@ -380,7 +377,7 @@ function SignInStartInternal(): JSX.Element {
switch (res.status) {
case 'needs_identifier':
// Check if we need to initiate an enterprise sso flow
if (res.supportedFirstFactors?.some(ff => ff.strategy === 'saml' || ff.strategy === 'enterprise_sso')) {
if (res.supportedFirstFactors?.some(ff => ff.strategy === 'enterprise_sso')) {
await authenticateWithEnterpriseSSO();
}
break;
Expand Down
24 changes: 0 additions & 24 deletions packages/ui/src/components/SignIn/__tests__/SignInStart.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -312,30 +312,6 @@ describe('SignInStart', () => {
});
});

describe('SAML', () => {
it('initiates a SAML flow if saml is listed as a supported first factor', async () => {
const { wrapper, fixtures } = await createFixtures(f => {
f.withEmailAddress();
});
fixtures.signIn.create.mockReturnValueOnce(
Promise.resolve({
status: 'needs_identifier',
supportedFirstFactors: [{ strategy: 'saml' }],
} as unknown as SignInResource),
);
const { userEvent } = render(<SignInStart />, { wrapper });
await userEvent.type(screen.getByLabelText(/email address/i), 'hello@clerk.com');
await userEvent.click(screen.getByText('Continue'));
expect(fixtures.signIn.create).toHaveBeenCalled();
expect(fixtures.signIn.authenticateWithRedirect).toHaveBeenCalledWith({
strategy: 'enterprise_sso',
redirectUrl: 'http://localhost:3000/#/sso-callback',
redirectUrlComplete: '/',
continueSignIn: true,
});
});
});

describe('Enterprise SSO', () => {
it('initiates a Enterprise SSO flow if enterprise_sso is listed as the only supported first factor', async () => {
const { wrapper, fixtures } = await createFixtures(f => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ export function hasOptionalFields(
identifierAttribute: 'emailAddress' | 'phoneNumber' | 'username',
) {
const filteredFields = signUp.optionalFields.filter(field => {
// OAuth, Web3, and SAML fields, while optional, are not relevant once sign up has been initiated with an identifier.
if (field.startsWith('oauth_') || field.startsWith('web3_') || ['enterprise_sso', 'saml'].includes(field)) {
// OAuth, Web3, and Enterprise SSO fields, while optional, are not relevant once sign up has been initiated with an identifier.
if (field.startsWith('oauth_') || field.startsWith('web3_') || field === 'enterprise_sso') {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/SignUp/SignUpStart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ function SignUpStartInternal(): JSX.Element {
// Keep the card in loading state during SSO redirect to prevent UI flicker
// This is necessary because there's a brief delay between initiating the SSO flow
// and the actual redirect to the external Identity Provider
const isRedirectingToSSOProvider = signUp.missingFields.some(mf => mf === 'saml' || mf === 'enterprise_sso');
const isRedirectingToSSOProvider = signUp.missingFields.some(mf => mf === 'enterprise_sso');
if (isRedirectingToSSOProvider) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ describe('AccountPage', () => {
},
verification: {
status: 'verified',
strategy: 'saml',
strategy: 'enterprise_sso',
verified_at_client: 'foo',
attempts: 0,
error: {
Expand Down Expand Up @@ -190,7 +190,7 @@ describe('AccountPage', () => {
},
verification: {
status: 'verified',
strategy: 'saml',
strategy: 'enterprise_sso',
verified_at_client: 'foo',
attempts: 0,
error: {
Expand Down Expand Up @@ -250,7 +250,7 @@ describe('AccountPage', () => {
},
verification: {
status: 'verified',
strategy: 'saml',
strategy: 'enterprise_sso',
verified_at_client: 'foo',
attempts: 0,
error: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import { describe, expect, it } from 'vitest';

import { bindCreateFixtures } from '@/test/create-fixtures';
Expand Down Expand Up @@ -50,7 +49,7 @@ const withInactiveEnterpriseConnection = createFixtures.config(f => {
},
verification: {
status: 'verified',
strategy: 'saml',
strategy: 'enterprise_sso',
verified_at_client: 'foo',
attempts: 0,
error: {
Expand Down Expand Up @@ -201,7 +200,7 @@ const withSamlEnterpriseConnection = createFixtures.config(f => {
},
verification: {
status: 'verified',
strategy: 'saml',
strategy: 'enterprise_sso',
verified_at_client: 'foo',
attempts: 0,
error: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ describe('PasswordSection', () => {
},
verification: {
status: 'verified',
strategy: 'saml',
strategy: 'enterprise_sso',
verified_at_client: 'foo',
attempts: 0,
error: {
Expand Down Expand Up @@ -215,7 +215,7 @@ describe('PasswordSection', () => {
},
verification: {
status: 'verified',
strategy: 'saml',
strategy: 'enterprise_sso',
verified_at_client: 'foo',
attempts: 0,
error: {
Expand Down Expand Up @@ -381,7 +381,7 @@ describe('PasswordSection', () => {
},
verification: {
status: 'verified',
strategy: 'saml',
strategy: 'enterprise_sso',
verified_at_client: 'foo',
attempts: 0,
error: {
Expand Down Expand Up @@ -455,7 +455,7 @@ describe('PasswordSection', () => {
},
verification: {
status: 'verified',
strategy: 'saml',
strategy: 'enterprise_sso',
verified_at_client: 'foo',
attempts: 0,
error: {
Expand Down
Loading
Loading