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:
parent
308ce7031a
commit
d2f938803b
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue