Skip to content

Commit

Permalink
fix(clerk-js): Remove deeply cloned check
Browse files Browse the repository at this point in the history
  • Loading branch information
octoper committed Feb 21, 2025
1 parent d206b90 commit a8a8982
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import type { LocalizationKey } from '../../customizables';
import { Col, descriptors, Flex, Flow, localizationKeys } from '../../customizables';
import { ArrowBlockButton, BackLink, Card, Header } from '../../elements';
import { useCardState } from '../../elements/contexts';
import { useReverificationAlternativeStrategies } from '../../hooks/useAlternativeStrategies';
import { ChatAltIcon, Email, LockClosedIcon } from '../../icons';
import { formatSafeIdentifier } from '../../utils';
import { useReverificationAlternativeStrategies } from './useReverificationAlternativeStrategies';
import { useUserVerificationSession } from './useUserVerificationSession';
import { withHavingTrouble } from './withHavingTrouble';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,18 @@ export const UVFactorOneCodeForm = (props: UVFactorOneCodeFormProps) => {
};

return (
<div>
<VerificationCodeCard
cardTitle={props.cardTitle}
cardSubtitle={props.cardSubtitle}
inputLabel={props.inputLabel}
resendButton={props.resendButton}
onCodeEntryFinishedAction={action}
onResendCodeClicked={prepare}
safeIdentifier={props.factor.safeIdentifier}
profileImageUrl={session?.user?.imageUrl}
onShowAlternativeMethodsClicked={props.onShowAlternativeMethodsClicked}
showAlternativeMethods={props.showAlternativeMethods}
onBackLinkClicked={props.onBackLinkClicked}
/>
</div>
<VerificationCodeCard
cardTitle={props.cardTitle}
cardSubtitle={props.cardSubtitle}
inputLabel={props.inputLabel}
resendButton={props.resendButton}
onCodeEntryFinishedAction={action}
onResendCodeClicked={prepare}
safeIdentifier={props.factor.safeIdentifier}
profileImageUrl={session?.user?.imageUrl}
onShowAlternativeMethodsClicked={props.onShowAlternativeMethodsClicked}
showAlternativeMethods={props.showAlternativeMethods}
onBackLinkClicked={props.onBackLinkClicked}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import React, { useEffect } from 'react';

import { useEnvironment } from '../../contexts';
import { ErrorCard, LoadingCard, useCardState, withCardStateProvider } from '../../elements';
import { useReverificationAlternativeStrategies } from '../../hooks/useAlternativeStrategies';
import { localizationKeys } from '../../localization';
import { useRouter } from '../../router';
import { determineStartingSignInFactor, factorHasLocalStrategy } from '../SignIn/utils';
import { AlternativeMethods } from './AlternativeMethods';
import { useReverificationAlternativeStrategies } from './useReverificationAlternativeStrategies';
import { UserVerificationFactorOnePasswordCard } from './UserVerificationFactorOnePassword';
import { useUserVerificationSession, withUserVerificationSessionGuard } from './useUserVerificationSession';
import { UVFactorOneEmailCodeCard } from './UVFactorOneEmailCodeCard';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { SignInFactor, SignInFirstFactor } from '@clerk/types';
import { useMemo } from 'react';

import { allStrategiesButtonsComparator } from '../../utils';
import { factorHasLocalStrategy, isResetPasswordStrategy } from '../SignIn/utils';

const factorsAreEqual = (a: SignInFactor | null | undefined, b: SignInFactor | null | undefined) => {
if (!a || !b) {
return false;
}

if (a.strategy === 'email_code' && b.strategy === 'email_code') {
return a.emailAddressId === b.emailAddressId;
}

if (a.strategy === 'phone_code' && b.strategy === 'phone_code') {
return a.phoneNumberId === b.phoneNumberId;
}

return a.strategy === b.strategy;
};

export function useReverificationAlternativeStrategies<T = SignInFirstFactor>({
filterOutFactor,
supportedFirstFactors,
}: {
filterOutFactor: SignInFactor | null | undefined;
supportedFirstFactors: SignInFirstFactor[] | null | undefined;
}) {
const firstFactors = supportedFirstFactors
? supportedFirstFactors.filter(f => !isResetPasswordStrategy(f.strategy))
: [];
const shouldAllowForAlternativeStrategies = firstFactors && firstFactors.length > 0;

const firstPartyFactors = useMemo(
() =>
supportedFirstFactors
? (supportedFirstFactors
.filter(f => !f.strategy.startsWith('oauth_'))
.filter(factor => factorHasLocalStrategy(factor))
.filter(factor => !factorsAreEqual(factor, filterOutFactor))
// Only include passkey if the device supports it.
// @ts-ignore Types are not public yet.
.filter(factor => (factor.strategy === 'passkey' ? isWebAuthnSupported() : true))
.sort(allStrategiesButtonsComparator) as T[])
: [],
[supportedFirstFactors, filterOutFactor],
);

return {
hasAnyStrategy: shouldAllowForAlternativeStrategies,
hasFirstParty: firstPartyFactors && firstPartyFactors.length > 0,
firstPartyFactors,
};
}
30 changes: 0 additions & 30 deletions packages/clerk-js/src/ui/hooks/useAlternativeStrategies.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { isDeeplyEqual } from '@clerk/shared/react/index';
import { isWebAuthnSupported } from '@clerk/shared/webauthn';
import type { SignInFactor, SignInFirstFactor } from '@clerk/types';

Expand Down Expand Up @@ -36,32 +35,3 @@ export function useAlternativeStrategies<T = SignInFirstFactor>({
firstPartyFactors,
};
}

export function useReverificationAlternativeStrategies<T = SignInFirstFactor>({
filterOutFactor,
supportedFirstFactors: _supportedFirstFactors,
}: {
filterOutFactor: SignInFactor | null | undefined;
supportedFirstFactors: SignInFirstFactor[] | null | undefined;
}) {
const supportedFirstFactors = _supportedFirstFactors || [];

const firstFactors = supportedFirstFactors.filter(f => !isResetPasswordStrategy(f.strategy));

const shouldAllowForAlternativeStrategies = firstFactors.length > 0;

const firstPartyFactors = supportedFirstFactors
.filter(f => !f.strategy.startsWith('oauth_'))
.filter(factor => factorHasLocalStrategy(factor))
.filter(factor => !isDeeplyEqual(factor, filterOutFactor))
// Only include passkey if the device supports it.
// @ts-ignore Types are not public yet.
.filter(factor => (factor.strategy === 'passkey' ? isWebAuthnSupported() : true))
.sort(allStrategiesButtonsComparator) as T[];

return {
hasAnyStrategy: shouldAllowForAlternativeStrategies,
hasFirstParty: firstPartyFactors.length > 0,
firstPartyFactors,
};
}

0 comments on commit a8a8982

Please sign in to comment.