Captcha.vue 1.8 KB

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