Skip to content

Commit ed94db2

Browse files
authored
[Core 1 backport] fix(clerk-js): Improvements on Smart bot protection (#4943)
1 parent aa9c815 commit ed94db2

File tree

6 files changed

+32
-7
lines changed

6 files changed

+32
-7
lines changed

.changeset/eighty-tigers-doubt.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@clerk/clerk-js': patch
3+
---
4+
5+
Improvements on Smart bot protection
6+
7+
- Fix bot protection layout shift on the sign-up form.
8+
- Fix the transfer flow when captcha is interactive.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
"turbo:clean": "turbo daemon clean",
3939
"update:lockfile": "npm run nuke && npm install -D --arch=x64 --platform=linux turbo && npm install -D --arch=arm64 --platform=darwin turbo",
4040
"version": "changeset version && ./scripts/version-info.sh",
41+
"version-packages:snapshot": "./scripts/snapshot.mjs",
4142
"version:canary": "./scripts/canary.mjs",
42-
"version:snapshot": "./scripts/snapshot.mjs",
4343
"yalc:all": "for d in packages/*/; do echo $d; cd $d; yalc push --replace --sig; cd '../../'; done"
4444
},
4545
"devDependencies": {

packages/clerk-js/src/ui/components/SignUp/SignUpForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export const SignUpForm = (props: SignUpFormProps) => {
101101
</Form.ControlRow>
102102
)}
103103
<Col center>
104-
<CaptchaElement />
104+
<CaptchaElement maxHeight='0' />
105105
<Form.SubmitButton>Continue</Form.SubmitButton>
106106
</Col>
107107
</Form.Root>

packages/clerk-js/src/ui/components/SignUp/SignUpStart.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ function _SignUpStart(): JSX.Element {
273273
/>
274274
)}
275275
</SocialButtonsReversibleContainerWithDivider>
276-
{!shouldShowForm && <CaptchaElement />}
276+
{!shouldShowForm && <CaptchaElement maxHeight='0' />}
277277
</Flex>
278278
<Footer.Root>
279279
<Footer.Action elementId='signUp'>
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { CAPTCHA_ELEMENT_ID } from '../../utils/captcha';
22
import { Box } from '../customizables';
33

4-
export const CaptchaElement = () => (
4+
type CaptchaElementProps = {
5+
maxHeight?: string;
6+
};
7+
8+
export const CaptchaElement = ({ maxHeight }: CaptchaElementProps) => (
59
<Box
610
id={CAPTCHA_ELEMENT_ID}
7-
sx={t => ({ display: 'none', marginBottom: t.space.$6, alignSelf: 'center' })}
11+
sx={{ display: 'block', alignSelf: 'center', maxHeight }}
812
/>
913
);

packages/clerk-js/src/utils/captcha/turnstile.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ interface RenderOptions {
4040
* @param errorCode string
4141
*/
4242
'error-callback'?: (errorCode: string) => void;
43+
/**
44+
* A JavaScript callback invoked before the challenge enters interactive mode.
45+
*/
46+
'before-interactive-callback'?: () => void;
4347
/**
4448
* A JavaScript callback invoked when a given client/browser is not supported by the widget.
4549
*/
@@ -145,7 +149,6 @@ export const getTunstileToken = async (captchaOptions: {
145149
} else {
146150
const visibleDiv = document.getElementById(CAPTCHA_ELEMENT_ID);
147151
if (visibleDiv) {
148-
visibleDiv.style.display = 'block';
149152
widgetDiv = visibleDiv;
150153
} else {
151154
console.error('Captcha DOM element not found. Using invisible captcha widget.');
@@ -163,6 +166,14 @@ export const getTunstileToken = async (captchaOptions: {
163166
callback: function (token: string) {
164167
resolve([token, id]);
165168
},
169+
'before-interactive-callback': () => {
170+
const visibleWidget = document.getElementById(CAPTCHA_ELEMENT_ID);
171+
if (visibleWidget) {
172+
visibleWidget.style.maxHeight = 'unset';
173+
visibleWidget.style.minHeight = '68px'; // this is the height of the Turnstile widget
174+
visibleWidget.style.marginBottom = '1.5rem';
175+
}
176+
},
166177
'error-callback': function (errorCode) {
167178
errorCodes.push(errorCode);
168179
/**
@@ -211,7 +222,9 @@ export const getTunstileToken = async (captchaOptions: {
211222
if (isInvisibleWidget) {
212223
document.body.removeChild(widgetDiv as HTMLElement);
213224
} else {
214-
(widgetDiv as HTMLElement).style.display = 'none';
225+
(widgetDiv as HTMLElement).style.maxHeight = '0';
226+
(widgetDiv as HTMLElement).style.minHeight = 'unset';
227+
(widgetDiv as HTMLElement).style.marginBottom = 'unset';
215228
}
216229
}
217230
}

0 commit comments

Comments
 (0)