Skip to content

Commit 9f57237

Browse files
committed
Recaptcha improvements #3477
1 parent ded2ca4 commit 9f57237

4 files changed

Lines changed: 86 additions & 42 deletions

File tree

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
'use client'
2+
import { FriendlyCaptchaContext, FriendlyCaptchaContextProvider } from '@/contexts/FriendlyCaptchaContext'
23
import { FriendlyCaptchaSDK } from '@friendlycaptcha/sdk'
3-
import { type ReactNode, useEffect, useState } from 'react'
4-
import { FriendlyCaptchaContext } from '@/templates/forms/FriendlyCaptcha'
4+
import { type ReactNode, useCallback, useEffect, useState } from 'react'
5+
56

67
export const FriendlyCaptchaSdkWrapper = ({
78
children,
89
}: {
910
children: ReactNode
1011
}) => {
1112
const [sdk, setSdk] = useState<FriendlyCaptchaSDK|undefined>(undefined)
13+
const [isHuman, setIsHuman] = useState(false)
1214

1315
useEffect(() => {
1416
if (!sdk) {
1517
setSdk(new FriendlyCaptchaSDK())
1618
}
1719
}, [])
1820

21+
const setHumanState = useCallback((isHuman:boolean)=>{
22+
setIsHuman(isHuman)
23+
},[setIsHuman,isHuman])
24+
1925
return (
20-
<FriendlyCaptchaContext.Provider value={sdk}>
26+
<FriendlyCaptchaContextProvider sdk={sdk} setIsHuman={setHumanState} isHuman={isHuman}>
2127
{children}
22-
</FriendlyCaptchaContext.Provider>
28+
</FriendlyCaptchaContextProvider>
2329
)
2430
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use client'
2+
import { FriendlyCaptchaSDK } from '@friendlycaptcha/sdk'
3+
import { createContext, Dispatch, PropsWithChildren, type RefObject, SetStateAction, useState } from 'react'
4+
5+
type Props = {
6+
isHuman: boolean,
7+
setIsHuman:(isHuman:boolean) => void,
8+
sdk: FriendlyCaptchaSDK|undefined
9+
}
10+
11+
12+
export const FriendlyCaptchaContext = createContext<Props>({
13+
isHuman: false,
14+
setIsHuman:(isHuman:boolean) => {},
15+
sdk:undefined
16+
})
17+
18+
export const FriendlyCaptchaContextProvider = ({
19+
children,
20+
isHuman,
21+
sdk,
22+
setIsHuman
23+
}: PropsWithChildren<{isHuman:boolean, sdk:FriendlyCaptchaSDK|undefined, setIsHuman:(isHuman:boolean)=>void}>) => {
24+
return (
25+
<FriendlyCaptchaContext.Provider value={{ isHuman:isHuman, setIsHuman, sdk }}>
26+
{children}
27+
</FriendlyCaptchaContext.Provider>
28+
)
29+
}

web/core/Link/DownloadableLink.tsx

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useTranslations } from 'next-intl'
2-
import { forwardRef, useCallback, useState } from 'react'
2+
import { forwardRef, useCallback, useContext, useState } from 'react'
33
//BsFiletypeDoc, BsFiletypeMov,
44
import {
55
BsFiletypeJpg,
@@ -18,6 +18,7 @@ import type { LinkType } from '@/types'
1818
import { ArrowRight } from '../../icons'
1919
import { BaseLink } from './BaseLink'
2020
import { getArrowElement, type ResourceLinkProps } from './ResourceLink'
21+
import { FriendlyCaptchaContext } from '@/contexts/FriendlyCaptchaContext'
2122

2223
type Variants = 'default' | 'fit'
2324
type Type = 'simple' | 'resource' | 'stickyMenu'
@@ -63,6 +64,7 @@ const DownloadableLink = forwardRef<HTMLDivElement, DownloadableLinkProps>(
6364
const openInNewTab = ['pdf', 'png', 'jpg']
6465

6566
const [notHuman, setNotHuman] = useState(false)
67+
const {isHuman, setIsHuman} = useContext(FriendlyCaptchaContext)
6668

6769
const variantClassName: Partial<Record<string, string>> = {
6870
default: 'w-full',
@@ -120,6 +122,7 @@ const DownloadableLink = forwardRef<HTMLDivElement, DownloadableLinkProps>(
120122
setIsFriendlyChallengeDone(true)
121123
const result = await verifyCaptcha(solution)
122124
setNotHuman(result !== true)
125+
setIsHuman(result==true)
123126
},
124127
[],
125128
)
@@ -153,9 +156,38 @@ const DownloadableLink = forwardRef<HTMLDivElement, DownloadableLinkProps>(
153156
</div>
154157
)
155158

159+
const downloadable = (
160+
<BaseLink
161+
className={twMerge(
162+
`${commonResourceLinkWrapperClassName}`,
163+
!isHuman && 'pt-20',
164+
)}
165+
type={linkType}
166+
href={linkType === 'downloadableFile' ? fileUrl : url}
167+
{...(extension &&
168+
openInNewTab?.includes(extension.toLowerCase()) && {
169+
target: '_blank',
170+
})}
171+
>
172+
<span
173+
className={`flex h-full w-inherit items-center justify-start gap-x-2 ${contentVariantClassName[variant]}`}
174+
>
175+
{linkElement}
176+
{getArrowElement(
177+
extension && openInNewTab?.includes(extension.toLowerCase())
178+
? 'externalUrl'
179+
: linkType,
180+
)}
181+
</span>
182+
183+
<span className='h-px w-[0%] bg-grey-40 transition-all duration-300 group-hover:w-full' />
184+
</BaseLink>
185+
)
186+
187+
156188
return (
157189
<div ref={ref}>
158-
<button
190+
{ !isHuman && <button
159191
type='button'
160192
onClick={handleRequestFile}
161193
className={
@@ -192,7 +224,8 @@ const DownloadableLink = forwardRef<HTMLDivElement, DownloadableLinkProps>(
192224
<div className='h-px w-[0%] bg-grey-40 transition-all duration-300 group-hover:w-full' />
193225
)}
194226
</button>
195-
{showModal && (
227+
}
228+
{ showModal && !notHuman &&(
196229
<Modal
197230
isOpen={showModal}
198231
onClose={handleClose}
@@ -226,34 +259,12 @@ const DownloadableLink = forwardRef<HTMLDivElement, DownloadableLinkProps>(
226259
</Typography>
227260
)}
228261
{isFriendlyChallengeDone && !notHuman && (
229-
<BaseLink
230-
className={twMerge(
231-
`${commonResourceLinkWrapperClassName}`,
232-
'pt-20',
233-
)}
234-
type={linkType}
235-
href={linkType === 'downloadableFile' ? fileUrl : url}
236-
{...(extension &&
237-
openInNewTab?.includes(extension.toLowerCase()) && {
238-
target: '_blank',
239-
})}
240-
>
241-
<span
242-
className={`flex h-full w-inherit items-center justify-start gap-x-2 ${contentVariantClassName[variant]}`}
243-
>
244-
{linkElement}
245-
{getArrowElement(
246-
extension && openInNewTab?.includes(extension.toLowerCase())
247-
? 'externalUrl'
248-
: linkType,
249-
)}
250-
</span>
251-
252-
<span className='h-px w-[0%] bg-grey-40 transition-all duration-300 group-hover:w-full' />
253-
</BaseLink>
262+
downloadable
254263
)}
255264
</Modal>
256-
)}
265+
266+
)}
267+
{isHuman && downloadable}
257268
</div>
258269
)
259270
},

web/templates/forms/FriendlyCaptcha.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
'use client'
22
import type {
3-
FriendlyCaptchaSDK,
43
StartMode,
54
WidgetHandle,
65
} from '@friendlycaptcha/sdk'
76
import { useLocale } from 'next-intl'
8-
import { createContext, useContext, useEffect, useRef } from 'react'
7+
import { useContext, useEffect, useRef } from 'react'
98
import { friendlyCaptcha } from '../../lib/config'
10-
11-
export const FriendlyCaptchaContext = createContext<
12-
FriendlyCaptchaSDK | undefined
13-
>(undefined)
9+
import { FriendlyCaptchaContext } from '@/contexts/FriendlyCaptchaContext'
1410

1511
const FriendlyCaptcha = ({
1612
doneCallback,
@@ -23,12 +19,12 @@ const FriendlyCaptcha = ({
2319
}) => {
2420
const container = useRef(null)
2521
const widget = useRef<WidgetHandle>(null)
26-
const sdk = useContext(FriendlyCaptchaContext)
22+
const fRCContext = useContext(FriendlyCaptchaContext)
2723
const locale = useLocale()
2824

2925
useEffect(() => {
30-
if (!widget.current && container.current && sdk) {
31-
widget.current = sdk?.createWidget({
26+
if (!widget.current && container.current && fRCContext?.sdk) {
27+
widget.current = fRCContext?.sdk?.createWidget({
3228
element: container.current,
3329
sitekey: friendlyCaptcha.siteKey,
3430
startMode: startMode,
@@ -59,6 +55,8 @@ const FriendlyCaptcha = ({
5955
}
6056
}, [doneCallback, errorCallback, locale, startMode])
6157

58+
59+
6260
return <div ref={container} />
6361
}
6462

0 commit comments

Comments
 (0)