Captcha.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <template>
  2. <div class="d-flex flex-column container">
  3. <div id="captchaBox" :class="show ? '' : 'hidden'" />
  4. <vue-hcaptcha
  5. :sitekey="siteKey"
  6. challenge-container="captchaBox"
  7. @opened="show = true"
  8. @closed="show = false"
  9. @verify="onVerify"
  10. @expired="onExpire"
  11. @challenge-expired="onChallengeExpire"
  12. @error="onError"
  13. />
  14. <v-checkbox
  15. v-model="honeyPotChecked"
  16. :rules="[validateCaptchaState]"
  17. class="hidden-ctrl"
  18. />
  19. </div>
  20. </template>
  21. <script setup lang="ts">
  22. import VueHcaptcha from '@hcaptcha/vue3-hcaptcha'
  23. import type { Ref } from 'vue'
  24. const runtimeConfig = useRuntimeConfig()
  25. const siteKey = runtimeConfig.public.hCaptchaSiteKey
  26. const show: Ref<boolean> = ref(false)
  27. const verified: Ref<boolean> = ref(false)
  28. const expired: Ref<boolean> = ref(false)
  29. const token: Ref<string> = ref('')
  30. const eKey: Ref<string> = ref('')
  31. const error: Ref<string> = ref('')
  32. // La case étant masquée, si elle est cochée, alors on peut en déduire
  33. // qu'on a affaire un robot (voir mécanisme du honey pot)
  34. const honeyPotChecked: Ref<boolean> = ref(false)
  35. const emit = defineEmits(['update'])
  36. const validateCaptchaState = () =>
  37. (verified.value && !honeyPotChecked.value) ||
  38. 'Veuillez procéder à la vérification'
  39. function onVerify(tokenStr: string, ekey: string) {
  40. verified.value = true
  41. token.value = tokenStr
  42. eKey.value = ekey
  43. emit('update', true)
  44. show.value = false
  45. }
  46. function onExpire() {
  47. verified.value = false
  48. token.value = ''
  49. eKey.value = ''
  50. expired.value = true
  51. }
  52. function onChallengeExpire() {
  53. verified.value = false
  54. token.value = ''
  55. eKey.value = ''
  56. expired.value = true
  57. }
  58. function onError(err: string) {
  59. token.value = ''
  60. eKey.value = ''
  61. error.value = err
  62. console.log(`Error: ${err}`)
  63. if (process.dev) {
  64. console.log('Dev mode: force captcha validation')
  65. verified.value = true
  66. }
  67. }
  68. </script>
  69. <style scoped lang="scss">
  70. .hidden-ctrl {
  71. :deep(.v-input__control) {
  72. display: none;
  73. }
  74. }
  75. .container {
  76. position: relative;
  77. }
  78. #captchaBox {
  79. z-index: 1000;
  80. position: absolute;
  81. bottom: 140px;
  82. box-shadow: 2px 2px 1px grey;
  83. border: solid 1px lightgray;
  84. background: white;
  85. @media (min-width: 600px) {
  86. left: -100px;
  87. }
  88. }
  89. .hidden {
  90. display: none;
  91. }
  92. </style>