Captcha.vue 1.7 KB

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