Captcha.vue 1.8 KB

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