PluginProbe
The Innovative Form Builder – IvyForms / 0.8.2
The Innovative Form Builder – IvyForms v0.8.2
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / public / fields / TurnstileFormField.vue

TurnstileFormField.vue in The Innovative Form Builder – IvyForms 0.8.2, at frontend/src/views/public/fields/TurnstileFormField.vue

152 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <div
3 v-if="isTurnstileConfigured"
4 class="ivyforms-turnstile-container ivyforms-flex ivyforms-flex-direction-column ivyforms-gap-12 ivyforms-width-100"
5 :class="{ 'ivyforms-turnstile-container--has-error': error }"
6 >
7 <Turnstile
8 :site-key="turnstileConfig.siteKey"
9 :theme="turnstileConfig.theme"
10 :language="turnstileConfig.language"
11 :error="turnstileError"
12 @verify="handleVerify"
13 @error="handleError"
14 @expire="handleExpire"
15 />
16
17 <div
18 v-if="turnstileError"
19 class="ivyforms-security-field-error ivyforms-flex ivyforms-align-items-center regular-14 ivyforms-mt-6 ivyforms-gap-4"
20 >
21 <IvyIcon name="danger" size="s" type="fill-duo" color="var(--map-status-error-symbol-0)" />
22 {{ turnstileError }}
23 </div>
24 </div>
25 <div v-else class="ivyforms-turnstile-not-configured ivyforms-width-100">
26 <IvyAlert :description="getLabel('turnstile_not_configured_public')" type="warning" />
27 </div>
28 </template>
29
30 <script setup lang="ts">
31 import { ref, computed, watch } from 'vue'
32 import { useLabels } from '@/composables/useLabels'
33 import Turnstile from '@/views/_components/turnstile/Turnstile.vue'
34 import IvyAlert from '@/views/_components/alert/IvyAlert.vue'
35 import IvyIcon from '@/views/_components/icon/IvyIcon.vue'
36 import type { Field } from '@/types/field'
37 import type { TurnstileConfig, WindowTurnstileConfig } from '@/types/turnstile/turnstile-interface'
38 import type { TurnstileTheme } from '@/types/turnstile/turnstile-type'
39
40 declare global {
41 interface Window {
42 wpIvyTurnstileConfig?: WindowTurnstileConfig | unknown[]
43 }
44 }
45
46 interface Props {
47 field: Field
48 modelValue?: string
49 error?: string
50 }
51
52 interface Emits {
53 (event: 'update:modelValue', value: string): void
54 }
55
56 const props = defineProps<Props>()
57 const emit = defineEmits<Emits>()
58
59 const { getLabel } = useLabels()
60 const turnstileToken = ref('')
61 const turnstileError = ref('')
62
63 // Check if Turnstile is configured
64 const isTurnstileConfigured = computed(() => {
65 // Check if global Turnstile config exists and is configured
66 if (!window.wpIvyTurnstileConfig || Array.isArray(window.wpIvyTurnstileConfig)) {
67 return false
68 }
69
70 const config = window.wpIvyTurnstileConfig as WindowTurnstileConfig
71 const turnstileData = config.turnstile
72
73 if (!turnstileData) {
74 return false
75 }
76
77 // Convert configured value to boolean (it might be string or number from PHP)
78 const isConfigured =
79 turnstileData.configured === true ||
80 turnstileData.configured === 1 ||
81 turnstileData.configured === '1'
82
83 return isConfigured && !!turnstileData.siteKey
84 })
85
86 // Get Turnstile configuration from window object
87 const turnstileConfig = computed<TurnstileConfig>(() => {
88 if (!window.wpIvyTurnstileConfig || Array.isArray(window.wpIvyTurnstileConfig)) {
89 return {
90 siteKey: '',
91 theme: 'auto',
92 language: '',
93 }
94 }
95
96 const config = window.wpIvyTurnstileConfig as WindowTurnstileConfig
97 const turnstileData = config.turnstile
98
99 if (!turnstileData) {
100 return {
101 siteKey: '',
102 theme: 'auto',
103 language: '',
104 }
105 }
106
107 return {
108 siteKey: turnstileData.siteKey || '',
109 theme: (turnstileData.theme as TurnstileTheme) || 'auto',
110 language: turnstileData.language || '',
111 }
112 })
113
114 // Handle successful verification
115 const handleVerify = (token: string) => {
116 turnstileToken.value = token
117 turnstileError.value = ''
118 emit('update:modelValue', token)
119 }
120
121 // Handle error
122 const handleError = (error: string) => {
123 turnstileError.value = error || getLabel('turnstile_verification_failed')
124 turnstileToken.value = ''
125 emit('update:modelValue', '')
126 }
127
128 // Handle expiration
129 const handleExpire = () => {
130 turnstileError.value = getLabel('turnstile_expired')
131 turnstileToken.value = ''
132 emit('update:modelValue', '')
133 }
134
135 // Watch for external errors
136 watch(
137 () => props.error,
138 (newError) => {
139 if (newError) {
140 turnstileError.value = newError
141 }
142 },
143 { immediate: true },
144 )
145 </script>
146
147 <style lang="scss" scoped>
148 .ivyforms-security-field-error {
149 color: var(--map-status-error-symbol-0);
150 }
151 </style>
152