Improve Captcha Provider Handling and Availability Checks

- Add conditional rendering for captcha based on site key availability
- Dynamically generate captcha options based on configured providers
- Prevent displaying captcha input when no providers are configured
- Add runtime config checks for captcha site keys
This commit is contained in:
Julien Nahum 2025-02-27 15:00:56 +08:00
parent 308ce7031a
commit d2f938803b
4 changed files with 46 additions and 8 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<div v-if="showCaptcha"> <div v-if="showCaptcha && isSiteKeyAvailable">
<RecaptchaV2 <RecaptchaV2
v-if="provider === 'recaptcha'" v-if="provider === 'recaptcha'"
:key="`recaptcha-${componentKey}`" :key="`recaptcha-${componentKey}`"
@ -68,6 +68,15 @@ const componentKey = ref(0)
const formFieldName = computed(() => props.provider === 'recaptcha' ? 'g-recaptcha-response' : 'h-captcha-response') const formFieldName = computed(() => props.provider === 'recaptcha' ? 'g-recaptcha-response' : 'h-captcha-response')
const isSiteKeyAvailable = computed(() => {
if (props.provider === 'recaptcha') {
return !!recaptchaSiteKey
} else if (props.provider === 'hcaptcha') {
return !!hCaptchaSiteKey
}
return false
})
// Watch for provider changes to reset the form field // Watch for provider changes to reset the form field
watch(() => props.provider, async (newProvider, oldProvider) => { watch(() => props.provider, async (newProvider, oldProvider) => {
if (newProvider !== oldProvider) { if (newProvider !== oldProvider) {

View File

@ -78,7 +78,7 @@
<!-- Captcha --> <!-- Captcha -->
<div class="mb-3 px-2 mt-4 mx-auto w-max"> <div class="mb-3 px-2 mt-4 mx-auto w-max">
<CaptchaInput <CaptchaInput
v-if="form.use_captcha && isLastPage" v-if="form.use_captcha && isLastPage && hasCaptchaProviders && isCaptchaProviderAvailable"
ref="captcha" ref="captcha"
:provider="form.captcha_provider" :provider="form.captcha_provider"
:form="dataForm" :form="dataForm"
@ -178,6 +178,11 @@ export default {
const recordsStore = useRecordsStore() const recordsStore = useRecordsStore()
const workingFormStore = useWorkingFormStore() const workingFormStore = useWorkingFormStore()
const dataForm = ref(useForm()) const dataForm = ref(useForm())
const config = useRuntimeConfig()
const hasCaptchaProviders = computed(() => {
return config.public.hCaptchaSiteKey || config.public.recaptchaSiteKey
})
return { return {
dataForm, dataForm,
@ -191,6 +196,7 @@ export default {
// Used for admin previews // Used for admin previews
selectedFieldIndex: computed(() => workingFormStore.selectedFieldIndex), selectedFieldIndex: computed(() => workingFormStore.selectedFieldIndex),
showEditFieldSidebar: computed(() => workingFormStore.showEditFieldSidebar), showEditFieldSidebar: computed(() => workingFormStore.showEditFieldSidebar),
hasCaptchaProviders
} }
}, },
@ -302,6 +308,15 @@ export default {
return { return {
'--form-color': this.form.color '--form-color': this.form.color
} }
},
isCaptchaProviderAvailable() {
const config = useRuntimeConfig()
if (this.form.captcha_provider === 'recaptcha') {
return !!config.public.recaptchaSiteKey
} else if (this.form.captcha_provider === 'hcaptcha') {
return !!config.public.hCaptchaSiteKey
}
return false
} }
}, },

View File

@ -58,7 +58,7 @@
</div> </div>
</template> </template>
<div class="w-full border-t pt-4"> <div class="w-full border-t pt-4 mt-4">
<h4 class="font-semibold"> <h4 class="font-semibold">
Link Privacy Link Privacy
</h4> </h4>

View File

@ -72,7 +72,7 @@
<p class="text-gray-500 text-sm"> <p class="text-gray-500 text-sm">
Protect your form, and your sensitive files. Protect your form, and your sensitive files.
</p> </p>
<div class="flex items-start gap-6 flex-wrap"> <div v-if="hasCaptchaProviders" class="flex items-start gap-6 flex-wrap">
<ToggleSwitchInput <ToggleSwitchInput
name="use_captcha" name="use_captcha"
:form="form" :form="form"
@ -95,9 +95,23 @@
<script setup> <script setup>
const workingFormStore = useWorkingFormStore() const workingFormStore = useWorkingFormStore()
const { content: form } = storeToRefs(workingFormStore) const { content: form } = storeToRefs(workingFormStore)
const config = useRuntimeConfig()
const captchaOptions = [ const hasCaptchaProviders = computed(() => {
{ name: 'reCAPTCHA', value: 'recaptcha' }, return config.public.hCaptchaSiteKey || config.public.recaptchaSiteKey
{ name: 'hCaptcha', value: 'hcaptcha' }, })
]
const captchaOptions = computed(() => {
const options = []
if (config.public.recaptchaSiteKey) {
options.push({ name: 'reCAPTCHA', value: 'recaptcha' })
}
if (config.public.hCaptchaSiteKey) {
options.push({ name: 'hCaptcha', value: 'hcaptcha' })
}
return options
})
</script> </script>