109 lines
2.7 KiB
Vue
109 lines
2.7 KiB
Vue
<script setup>
|
|
import { defineEmits, defineExpose, defineProps, watch, ref, onMounted } from 'vue';
|
|
|
|
import VueHcaptcha from '@hcaptcha/vue3-hcaptcha';
|
|
import { RecaptchaV2, useRecaptcha } from "vue3-recaptcha-v2";
|
|
import VueTurnstile from 'vue-turnstile';
|
|
|
|
const { handleReset: handleRecaptchaReset } = useRecaptcha();
|
|
|
|
const props = defineProps({
|
|
isVertical: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
hcaptchaSitekey: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
recaptchaSitekey: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
turnstileSitekey: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
});
|
|
const emit = defineEmits(['captchaVerified']);
|
|
|
|
const hcaptchaResponse = ref('');
|
|
const recaptchaResponse = ref('');
|
|
const turnstileToken = ref('');
|
|
|
|
const hcaptchaRef = ref(null);
|
|
const recaptchaWidgetId = ref('');
|
|
const turnstileRef = ref(null);
|
|
|
|
const handleHcaptchaVerify = (token) => {
|
|
hcaptchaResponse.value = token;
|
|
};
|
|
|
|
const handleHcaptchaExpired = () => {
|
|
hcaptchaResponse.value = '';
|
|
};
|
|
|
|
const handleRecaptchaLoad = (response) => {
|
|
recaptchaResponse.value = response;
|
|
}
|
|
|
|
const handleRecaptchaExpired = () => {
|
|
recaptchaResponse.value = '';
|
|
};
|
|
|
|
const handleWidgetId = (widgetId) => {
|
|
recaptchaWidgetId.value = widgetId;
|
|
};
|
|
|
|
watch(
|
|
() => [hcaptchaResponse.value, recaptchaResponse.value, turnstileToken.value],
|
|
([hcaptcha, recaptcha, turnstile]) => {
|
|
if (hcaptcha && recaptcha && turnstile) {
|
|
// All tokens are available
|
|
emit('captchaVerified', {
|
|
hCaptchaResponse: hcaptcha,
|
|
recaptchaResponse: recaptcha,
|
|
turnstileResponse: turnstile
|
|
});
|
|
}
|
|
}
|
|
);
|
|
|
|
const reset = () => {
|
|
hcaptchaRef.value?.reset();
|
|
if (recaptchaWidgetId.value) handleRecaptchaReset(recaptchaWidgetId.value);
|
|
turnstileRef.value?.reset();
|
|
};
|
|
|
|
defineExpose({
|
|
reset,
|
|
});
|
|
|
|
onMounted(() => {
|
|
console.log(props);
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="ts-content is-horizontally-fitted">
|
|
<div class="ts-wrap is-center-aligned is-middle-aligned" :class="{ 'is-vertical': props.isVertical }">
|
|
<VueHcaptcha
|
|
ref="hcaptchaRef"
|
|
:sitekey="props.hcaptchaSitekey"
|
|
@verify="handleHcaptchaVerify"
|
|
@expired="handleHcaptchaExpired"
|
|
@reset="handleHcaptchaExpired"
|
|
:reCaptchaCompat="false"
|
|
:theme="$darkMode ? 'dark' : 'light'"
|
|
/>
|
|
<RecaptchaV2
|
|
:sitekey="props.recaptchaSitekey"
|
|
@widgetId="handleWidgetId"
|
|
@expired-callback="handleRecaptchaExpired"
|
|
@load-callback="handleRecaptchaLoad"
|
|
:theme="$darkMode ? 'dark' : 'light'"
|
|
/>
|
|
<VueTurnstile :site-key="props.turnstileSitekey" ref="turnstileRef" v-model="turnstileToken" />
|
|
</div>
|
|
</div>
|
|
</template> |