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
5 changes: 5 additions & 0 deletions .changeset/eleven-phones-say.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/clerk-js': patch
---

fix: Appropriately handle last-used SAML strategies
22 changes: 22 additions & 0 deletions integration/tests/last-authentication-strategy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,28 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withEmailCodes] })(
await expect(socialButtonContainers.first().locator('.cl-button')).toHaveCount(3);
});

test('should show "Last used" badge when lastAuthenticationStrategy is saml_google', async ({ page, context }) => {
const u = createTestUtils({ app, page, context });
await mockLastAuthenticationStrategyResponse(page, 'saml_google');

await u.po.signIn.goTo();
await u.po.signIn.waitForMounted();

// Ensure "Last used" badge is present.
const lastUsedBadge = page.locator('.cl-lastAuthenticationStrategyBadge');
await expect(lastUsedBadge).toBeVisible();
await expect(lastUsedBadge).toHaveCount(1);

const btn = page.getByRole('button', { name: 'Last used Sign in with Google' });
await expect(btn).toBeVisible();

// Ensure the last used social button has been pulled to the first row.
const socialButtonContainers = u.page.locator('.cl-socialButtons');
await expect(socialButtonContainers).toHaveCount(2);
await expect(socialButtonContainers.first().locator('.cl-button__google')).toHaveCount(1);
await expect(socialButtonContainers.last().locator('.cl-button')).toHaveCount(2);
});

test('should show "Last used" badge when lastAuthenticationStrategy is oauth_google', async ({ page, context }) => {
const u = createTestUtils({ app, page, context });
await mockLastAuthenticationStrategyResponse(page, 'oauth_google');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const SignInSocialButtons = React.memo((props: SignInSocialButtonsProps)
return (
<SocialButtons
{...rest}
showLastAuthenticationStrategy={true}
showLastAuthenticationStrategy
idleAfterDelay={!shouldUsePopup}
oauthCallback={strategy => {
if (shouldUsePopup) {
Expand Down
8 changes: 7 additions & 1 deletion packages/clerk-js/src/ui/elements/SocialButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ export const SocialButtons = React.memo((props: SocialButtonsRootProps) => {
return strategies.includes(strategy as TStrategy);
};

const lastAuthenticationStrategy = clientLastAuth && isValidStrategy(clientLastAuth) ? clientLastAuth : null;
// Convert SAML strategies to OAuth strategies for consistency when matching last used strategy.
const convertedClientLastAuth = clientLastAuth?.startsWith('saml_')
? clientLastAuth.replace('saml_', 'oauth_')
: clientLastAuth;

const lastAuthenticationStrategy =
convertedClientLastAuth && isValidStrategy(convertedClientLastAuth) ? convertedClientLastAuth : null;

const { strategyRows, lastAuthenticationStrategyPresent } = distributeStrategiesIntoRows<TStrategy>(
[...strategies],
Expand Down