Skip to content

Commit bef5122

Browse files
committed
fixed captcha stuff in auth component
1 parent ab435dd commit bef5122

9 files changed

Lines changed: 214 additions & 66 deletions

File tree

packages/react-wallet-kit/src/components/auth/Email.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ function isValidEmail(email: string): boolean {
1111

1212
interface EmailInputProps {
1313
onContinue?: (email: string) => void;
14+
disabled?: boolean;
1415
}
1516

1617
export function EmailInput(props: EmailInputProps) {
@@ -39,7 +40,7 @@ export function EmailInput(props: EmailInputProps) {
3940
}
4041
};
4142

42-
const buttonDisabled = !emailIsValid;
43+
const buttonDisabled = !emailIsValid || (props.disabled ?? false);
4344

4445
const buttonClass = clsx(
4546
"transition-all duration-300",

packages/react-wallet-kit/src/components/auth/OTP.tsx

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { OtpType, TurnkeyError, TurnkeyErrorCodes } from "@turnkey/core";
88
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
99
import { faEnvelope, faPhone } from "@fortawesome/free-solid-svg-icons";
1010
import clsx from "clsx";
11+
import { Turnstile, type TurnstileInstance } from "@marsidev/react-turnstile";
12+
import { consumeCaptchaToken } from "../../utils/captcha";
1113

1214
interface OtpVerificationProps {
1315
contact: string;
@@ -17,7 +19,6 @@ interface OtpVerificationProps {
1719
alphanumeric?: boolean | undefined; // Whether the OTP is alphanumeric or numeric only. Defaults to true (alphanumeric).
1820
formattedContact?: string; // Optional formatted contact for display purposes
1921
sessionKey?: string; // Optional sessionKey for multisession
20-
turnstileToken?: string | null; // Optional Turnstile token for CAPTCHA verification
2122
onContinue?: (optCode: string) => Promise<void>; // Optional callback for continue action
2223
}
2324
export function OtpVerification(props: OtpVerificationProps) {
@@ -28,10 +29,9 @@ export function OtpVerification(props: OtpVerificationProps) {
2829
alphanumeric = true,
2930
formattedContact,
3031
sessionKey,
31-
turnstileToken,
3232
onContinue = null, // Default to null if not provided
3333
} = props;
34-
const { initOtp, completeOtp } = useTurnkey();
34+
const { initOtp, completeOtp, config, getTurnstileToken, setTurnstileToken } = useTurnkey();
3535
const { closeModal, isMobile } = useModal();
3636
const [submitting, setSubmitting] = useState<boolean>(false);
3737
const [resending, setResending] = useState<boolean>(false);
@@ -40,6 +40,12 @@ export function OtpVerification(props: OtpVerificationProps) {
4040
const [error, setError] = useState<string | null>(null);
4141
const [shaking, setShaking] = useState(false);
4242

43+
const turnstileRef = useRef<TurnstileInstance>(null);
44+
const [showTurnstilePrompt, setShowTurnstilePrompt] = useState(false);
45+
46+
const consumeToken = () =>
47+
consumeCaptchaToken(getTurnstileToken, setTurnstileToken, turnstileRef);
48+
4349
const shakeInput = () => {
4450
setShaking(true);
4551
setTimeout(() => setShaking(false), 250);
@@ -57,7 +63,7 @@ export function OtpVerification(props: OtpVerificationProps) {
5763
contact,
5864
otpType,
5965
...(sessionKey && { sessionKey }),
60-
...(turnstileToken && { captchaToken: turnstileToken }), // Pass the Turnstile token if it exists
66+
...(await consumeToken()),
6167
});
6268
closeModal();
6369
}
@@ -80,8 +86,8 @@ export function OtpVerification(props: OtpVerificationProps) {
8086
const id = await initOtp({
8187
otpType,
8288
contact,
83-
...(turnstileToken && { captchaToken: turnstileToken }),
84-
}); // Pass the Turnstile token if it exists
89+
...(await consumeToken()),
90+
});
8591
setOtpId(id);
8692
setResent(true);
8793
} catch (error) {
@@ -94,7 +100,7 @@ export function OtpVerification(props: OtpVerificationProps) {
94100
return (
95101
<div
96102
className={clsx(
97-
"flex items-center justify-center py-3",
103+
"flex flex-col items-center justify-center py-3",
98104
isMobile ? "w-full" : "min-w-96",
99105
)}
100106
>
@@ -154,6 +160,37 @@ export function OtpVerification(props: OtpVerificationProps) {
154160
<Spinner strokeWidth={1} className="size-1/2" />
155161
</div>
156162
)}
163+
{config?.turnstileSiteKey && !submitting && (
164+
<div className="mt-3 flex flex-col text-left w-full">
165+
{showTurnstilePrompt && (
166+
<p className="text-icon-text-light/70 dark:text-icon-text-dark/70 text-sm mb-0.5">
167+
Let us know you're human
168+
</p>
169+
)}
170+
<Turnstile
171+
ref={turnstileRef}
172+
siteKey={config.turnstileSiteKey}
173+
className="!w-full !block [&>iframe]:!w-full"
174+
onSuccess={(token) => {
175+
setTurnstileToken(token);
176+
}}
177+
onError={() => {
178+
setTurnstileToken(null);
179+
}}
180+
onExpire={() => {
181+
setTurnstileToken(null);
182+
}}
183+
onBeforeInteractive={() => {
184+
setShowTurnstilePrompt(true);
185+
}}
186+
options={{
187+
theme: config.ui?.darkMode ? "dark" : "light",
188+
appearance: "interaction-only",
189+
size: "flexible",
190+
}}
191+
/>
192+
</div>
193+
)}
157194
</div>
158195
);
159196
}

packages/react-wallet-kit/src/components/auth/Passkey.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ActionButton } from "../design/Buttons";
33
interface PasskeyButtonsProps {
44
onLogin: () => void;
55
onSignUp: () => void;
6+
disabled?: boolean;
67
}
78

89
export function PasskeyButtons(props: PasskeyButtonsProps) {
@@ -13,13 +14,15 @@ export function PasskeyButtons(props: PasskeyButtonsProps) {
1314
name="passkey-login-button"
1415
onClick={onLogin}
1516
className="w-full text-inherit bg-button-light dark:bg-button-dark"
17+
disabled={props.disabled ?? false}
1618
>
1719
Log in with passkey
1820
</ActionButton>
1921
<ActionButton
2022
name="passkey-signup-button"
2123
onClick={onSignUp}
2224
className="w-full bg-transparent text-primary-light dark:text-primary-dark border-none"
25+
disabled={props.disabled ?? false}
2326
>
2427
Sign up with passkey
2528
</ActionButton>

packages/react-wallet-kit/src/components/auth/Phone.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useTurnkey } from "../../providers/client/Hook";
77

88
interface PhoneNumberInputProps {
99
onContinue?: (phone: string, formattedPhone: string) => void;
10+
disabled?: boolean;
1011
}
1112

1213
export function PhoneNumberInput(props: PhoneNumberInputProps) {
@@ -29,7 +30,7 @@ export function PhoneNumberInput(props: PhoneNumberInputProps) {
2930
}
3031
};
3132

32-
const buttonDisabled = !isValid;
33+
const buttonDisabled = !isValid || (props.disabled ?? false);
3334

3435
const buttonClass = clsx(
3536
"transition-all duration-300",

packages/react-wallet-kit/src/components/auth/Wallet.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { useDebouncedCallback } from "../../utils/utils";
2222

2323
interface WalletAuthButtonProps {
2424
onContinue: () => Promise<void>;
25+
disabled?: boolean;
2526
}
2627
export function WalletAuthButton(props: WalletAuthButtonProps) {
2728
const { onContinue } = props;
@@ -43,6 +44,7 @@ export function WalletAuthButton(props: WalletAuthButtonProps) {
4344
onClick={handleContinue}
4445
loading={isLoading}
4546
className="w-full text-inherit bg-button-light dark:bg-button-dark"
47+
disabled={props.disabled ?? false}
4648
>
4749
Continue with wallet
4850
</ActionButton>

0 commit comments

Comments
 (0)