Captcha.vue 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. <template>
  2. <vue-hcaptcha
  3. :sitekey="siteKey"
  4. @verify="onVerify"
  5. @expired="onExpire"
  6. @challenge-expired="onChallengeExpire"
  7. @error="onError"
  8. />
  9. <v-checkbox
  10. v-model="honeyPotChecked"
  11. :rules="[validateCaptchaState]"
  12. class="hidden-ctrl"
  13. />
  14. </template>
  15. <script setup lang="ts">
  16. import VueHcaptcha from "@hcaptcha/vue3-hcaptcha";
  17. const runtimeConfig = useRuntimeConfig()
  18. const siteKey = runtimeConfig.public.hCaptchaSiteKey
  19. const verified: Ref<boolean> = ref(false);
  20. const expired: Ref<boolean> = ref(false);
  21. const token: Ref<string> = ref("");
  22. const eKey: Ref<string> = ref("");
  23. const error: Ref<string> = ref("");
  24. // La case étant masquée, si elle est cochée, alors on peut en déduire
  25. // qu'on a affaire un robot (voir mécanisme du honey pot)
  26. const honeyPotChecked: Ref<boolean> = ref(false)
  27. const emit = defineEmits(['update'])
  28. const validateCaptchaState = () =>
  29. verified.value && !honeyPotChecked.value ||
  30. "Veuillez procédez à la vérification";
  31. function onVerify(tokenStr: string, ekey: string) {
  32. verified.value = true;
  33. token.value = tokenStr;
  34. eKey.value = ekey;
  35. emit('update', true)
  36. }
  37. function onExpire() {
  38. verified.value = false;
  39. token.value = '';
  40. eKey.value = '';
  41. expired.value = true;
  42. }
  43. function onChallengeExpire() {
  44. verified.value = false;
  45. token.value = '';
  46. eKey.value = '';
  47. expired.value = true;
  48. }
  49. function onError(err: string) {
  50. token.value = '';
  51. eKey.value = '';
  52. error.value = err;
  53. console.log(`Error: ${err}`);
  54. if (process.dev) {
  55. console.log('Dev mode: force captcha validation')
  56. verified.value = true;
  57. }
  58. }
  59. </script>
  60. <style scoped lang="scss">
  61. .hidden-ctrl {
  62. :deep(.v-input__control) {
  63. display: none;
  64. }
  65. }
  66. </style>