@prosopo/client-bundle-example 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/assets/{ProcaptchaWidget-3gKvjeiH.js → ProcaptchaWidget-DrBDhP6X.js} +7 -7
- package/dist/assets/{ProcaptchaWidget-D6-M7iAv.js → ProcaptchaWidget-rAM-9Rap.js} +4 -4
- package/dist/assets/{asU8a-DCECA0Qe.js → asU8a-CJdNkNEq.js} +1 -1
- package/dist/assets/{bip39-BQoZog_M.js → bip39-Du2cANEV.js} +2 -2
- package/dist/assets/captcha-BhkVCEXM.css +1 -0
- package/dist/assets/{captchaComponentProvider-BW2eXmc3.js → captchaComponentProvider-DmV1WTrT.js} +4 -4
- package/dist/assets/{captchaRenderer-B_MgGzr9.js → captchaRenderer-RIsSZXCC.js} +2 -2
- package/dist/assets/{emotion-element-5486c51c.browser.esm-CCAJ8JId.js → emotion-element-5486c51c.browser.esm-C3u8NMUC.js} +127 -125
- package/dist/assets/frictionless-explicit-Dq_sNGRK.js +1 -0
- package/dist/assets/frictionless-implicit-Dq_sNGRK.js +1 -0
- package/dist/assets/{hash-BR0YLxPF.js → hash-_rWungeW.js} +1 -1
- package/dist/assets/image-explicit-DQvfVB7-.js +4 -0
- package/dist/assets/image-implicit-Bwa9QJO5.js +1 -0
- package/dist/assets/{index-WqEmiYQ_.js → index-BVr9fC_3.js} +4 -4
- package/dist/assets/{index-BYUYvvuq.js → index-Cu5oL_7b.js} +4 -4
- package/dist/assets/index-Dpt_5E72.js +1 -0
- package/dist/assets/{index-BCjHZ8o6.js → index-DxIFpl6U.js} +1 -1
- package/dist/assets/{index-2or4-1WF.js → index-Wgw2GQWq.js} +2 -2
- package/dist/assets/invisible-frictionless-explicit-DugBtRe4.js +4 -0
- package/dist/assets/invisible-frictionless-implicit-DYYos8W9.js +1 -0
- package/dist/assets/invisible-image-explicit-C5Z4gSb1.js +4 -0
- package/dist/assets/invisible-image-implicit-DfNFNlFj.js +1 -0
- package/dist/assets/invisible-pow-explicit-DjqGWFUb.js +4 -0
- package/dist/assets/invisible-pow-implicit-BRXL14FH.js +4 -0
- package/dist/assets/pow-explicit-BexxbnHM.js +4 -0
- package/dist/assets/pow-implicit-Dpt_5E72.js +1 -0
- package/dist/assets/procaptcha.bundle.js +1 -1
- package/dist/assets/{useTranslation-BPbGzrhj.js → useTranslation-CJplXtqb.js} +1 -1
- package/dist/frictionless-explicit.html +881 -0
- package/dist/frictionless-implicit.html +874 -0
- package/dist/image-explicit.html +877 -0
- package/dist/index.html +575 -74
- package/dist/invisible-frictionless-explicit.html +626 -283
- package/dist/invisible-frictionless-implicit.html +631 -173
- package/dist/invisible-image-explicit.html +627 -284
- package/dist/invisible-image-implicit.html +631 -173
- package/dist/invisible-pow-explicit.html +627 -284
- package/dist/invisible-pow-implicit.html +629 -177
- package/dist/plugins/explanation-injector.ts +250 -0
- package/dist/plugins/form-filler-injector.ts +233 -0
- package/dist/plugins/navigation-injector.ts +237 -89
- package/dist/plugins/status-log-injector.ts +199 -0
- package/dist/pow-explicit.html +877 -0
- package/dist/pow-implicit.html +881 -0
- package/package.json +1 -1
- package/vite.config.ts +32 -3
- package/dist/assets/frictionless-ZgzyuneX.js +0 -1
- package/dist/assets/index-BWsu-rGU.js +0 -1
- package/dist/assets/invisible-frictionless-explicit-DgCaJtPg.js +0 -1
- package/dist/assets/invisible-image-explicit-DgCaJtPg.js +0 -1
- package/dist/assets/invisible-pow-explicit-DgCaJtPg.js +0 -1
- package/dist/assets/pow-BW3QYcgP.js +0 -1
- package/dist/frictionless.html +0 -343
- package/dist/pow.html +0 -323
- /package/dist/assets/{modulepreload-polyfill-B5Qt9EMX.js → captcha-ByKnSsbG.js} +0 -0
|
@@ -1,150 +1,9 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<style>
|
|
8
|
-
body {
|
|
9
|
-
font-family: Arial, sans-serif;
|
|
10
|
-
margin: 0 auto;
|
|
11
|
-
padding: 20px;
|
|
12
|
-
}
|
|
13
|
-
form {
|
|
14
|
-
border: 1px solid #ddd;
|
|
15
|
-
padding: 20px;
|
|
16
|
-
border-radius: 5px;
|
|
17
|
-
}
|
|
18
|
-
label {
|
|
19
|
-
display: block;
|
|
20
|
-
margin-bottom: 5px;
|
|
21
|
-
}
|
|
22
|
-
input[type="text"],
|
|
23
|
-
input[type="email"] {
|
|
24
|
-
width: 100%;
|
|
25
|
-
padding: 8px;
|
|
26
|
-
margin-bottom: 15px;
|
|
27
|
-
border: 1px solid #ccc;
|
|
28
|
-
border-radius: 4px;
|
|
29
|
-
}
|
|
30
|
-
button {
|
|
31
|
-
background-color: #4CAF50;
|
|
32
|
-
color: white;
|
|
33
|
-
padding: 10px 15px;
|
|
34
|
-
border: none;
|
|
35
|
-
border-radius: 4px;
|
|
36
|
-
cursor: pointer;
|
|
37
|
-
}
|
|
38
|
-
button:hover {
|
|
39
|
-
background-color: #45a049;
|
|
40
|
-
}
|
|
41
|
-
#result {
|
|
42
|
-
margin-top: 15px;
|
|
43
|
-
padding: 10px;
|
|
44
|
-
border: 1px solid #ddd;
|
|
45
|
-
border-radius: 4px;
|
|
46
|
-
background-color: #f9f9f9;
|
|
47
|
-
display: none;
|
|
48
|
-
}
|
|
49
|
-
.console-output {
|
|
50
|
-
margin-top: 20px;
|
|
51
|
-
padding: 10px;
|
|
52
|
-
background-color: #f5f5f5;
|
|
53
|
-
border: 1px solid #ddd;
|
|
54
|
-
border-radius: 4px;
|
|
55
|
-
font-family: monospace;
|
|
56
|
-
white-space: pre-wrap;
|
|
57
|
-
max-height: 200px;
|
|
58
|
-
overflow-y: auto;
|
|
59
|
-
}
|
|
60
|
-
.info-box {
|
|
61
|
-
background-color: #e7f3fe;
|
|
62
|
-
border-left: 4px solid #2196F3;
|
|
63
|
-
padding: 15px;
|
|
64
|
-
margin: 20px 0;
|
|
65
|
-
}
|
|
66
|
-
</style>
|
|
67
|
-
<script type="text/javascript">
|
|
68
|
-
function onSubmit(token) {
|
|
69
|
-
console.log('Procaptcha verified, token:', token);
|
|
70
|
-
|
|
71
|
-
const name = document.getElementById('name').value;
|
|
72
|
-
const email = document.getElementById('email').value;
|
|
73
|
-
|
|
74
|
-
const resultElement = document.getElementById('result');
|
|
75
|
-
resultElement.textContent = `Form submitted with:
|
|
76
|
-
- Name: ${name}
|
|
77
|
-
- Email: ${email}
|
|
78
|
-
- Procaptcha verified: Yes`;
|
|
79
|
-
resultElement.style.display = 'block';
|
|
80
|
-
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function validate(event) {
|
|
85
|
-
event.preventDefault();
|
|
86
|
-
|
|
87
|
-
// Simple form validation
|
|
88
|
-
if (!document.getElementById('name').value) {
|
|
89
|
-
alert("Please enter your name");
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (!document.getElementById('email').value) {
|
|
94
|
-
alert("Please enter your email");
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
document.getElementById('console-output').innerHTML = '';
|
|
99
|
-
const originalConsoleLog = console.log;
|
|
100
|
-
const consoleOutput = document.getElementById('console-output');
|
|
101
|
-
|
|
102
|
-
console.log = function() {
|
|
103
|
-
originalConsoleLog.apply(console, arguments);
|
|
104
|
-
|
|
105
|
-
// Format and display the arguments in our custom console
|
|
106
|
-
const args = Array.from(arguments).map(arg => {
|
|
107
|
-
if (typeof arg === 'object') {
|
|
108
|
-
try {
|
|
109
|
-
return JSON.stringify(arg, null, 2);
|
|
110
|
-
} catch (e) {
|
|
111
|
-
return "[Object cannot be stringified]";
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return String(arg);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
consoleOutput.innerHTML += args.join(' ') + '<br>';
|
|
118
|
-
consoleOutput.style.display = 'block';
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
console.log('Executing Procaptcha verification...');
|
|
122
|
-
window.procaptcha.execute();
|
|
123
|
-
|
|
124
|
-
setTimeout(() => {
|
|
125
|
-
console.log = originalConsoleLog;
|
|
126
|
-
}, 1000);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function onloadCallback() {
|
|
130
|
-
console.log('Procaptcha script loaded, initializing explicit rendering');
|
|
131
|
-
|
|
132
|
-
// Render the Procaptcha widget
|
|
133
|
-
window.procaptcha.render(document.getElementById('procaptcha-container'), {
|
|
134
|
-
'siteKey': 'undefined',
|
|
135
|
-
'callback': onSubmit,
|
|
136
|
-
'captchaType': 'frictionless',
|
|
137
|
-
'size': 'invisible'
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
document.getElementById('submit-button').addEventListener('click', validate);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
144
|
-
// Set up the onload callback for Procaptcha
|
|
145
|
-
window.onProcaptchaLoad = onloadCallback;
|
|
146
|
-
});
|
|
147
|
-
</script>
|
|
4
|
+
<link href="https://cdn.muicss.com/mui-0.10.3/css/mui.min.css" rel="stylesheet" type="text/css"/>
|
|
5
|
+
<title>Procaptcha Frictionless Mode - Explicit Rendering</title>
|
|
6
|
+
<!-- Status log will be injected by the status-log-injector plugin -->
|
|
148
7
|
|
|
149
8
|
<style>
|
|
150
9
|
.nav-topbar {
|
|
@@ -153,60 +12,64 @@
|
|
|
153
12
|
margin-bottom: 20px;
|
|
154
13
|
transition: all 0.3s ease;
|
|
155
14
|
overflow: hidden;
|
|
156
|
-
max-height: 500px;
|
|
15
|
+
max-height: 500px;
|
|
157
16
|
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
|
17
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
|
158
18
|
}
|
|
159
19
|
.nav-topbar.collapsed {
|
|
160
|
-
max-height:
|
|
20
|
+
max-height: 60px;
|
|
161
21
|
}
|
|
162
22
|
.nav-container {
|
|
163
23
|
max-width: 1200px;
|
|
164
24
|
margin: 0 auto;
|
|
165
|
-
padding: 0
|
|
25
|
+
padding: 0 20px;
|
|
166
26
|
position: relative;
|
|
167
27
|
}
|
|
168
28
|
.nav-header {
|
|
169
29
|
display: flex;
|
|
170
30
|
justify-content: space-between;
|
|
171
31
|
align-items: center;
|
|
172
|
-
padding:
|
|
32
|
+
padding: 12px 0;
|
|
173
33
|
position: relative;
|
|
174
34
|
z-index: 20;
|
|
175
35
|
}
|
|
176
36
|
.nav-title {
|
|
177
37
|
color: white;
|
|
178
|
-
font-size:
|
|
179
|
-
font-weight:
|
|
38
|
+
font-size: 1.25rem;
|
|
39
|
+
font-weight: 600;
|
|
180
40
|
margin: 0;
|
|
181
41
|
display: flex;
|
|
182
42
|
align-items: center;
|
|
43
|
+
gap: 8px;
|
|
183
44
|
}
|
|
184
45
|
.nav-title-text {
|
|
185
|
-
margin-right:
|
|
46
|
+
margin-right: 8px;
|
|
186
47
|
}
|
|
187
48
|
.nav-title-hint {
|
|
188
|
-
font-size:
|
|
49
|
+
font-size: 0.875rem;
|
|
189
50
|
font-weight: normal;
|
|
190
51
|
opacity: 0;
|
|
191
52
|
transition: opacity 0.3s ease;
|
|
53
|
+
color: rgba(255,255,255,0.8);
|
|
192
54
|
}
|
|
193
55
|
.collapsed .nav-title-hint {
|
|
194
56
|
opacity: 0.8;
|
|
195
57
|
}
|
|
196
58
|
.nav-toggle {
|
|
197
|
-
background-color: rgba(
|
|
59
|
+
background-color: rgba(255,255,255,0.1);
|
|
198
60
|
color: white;
|
|
199
61
|
border: none;
|
|
200
|
-
padding:
|
|
62
|
+
padding: 8px 12px;
|
|
201
63
|
cursor: pointer;
|
|
202
|
-
border-radius:
|
|
64
|
+
border-radius: 6px;
|
|
203
65
|
z-index: 10;
|
|
204
66
|
display: flex;
|
|
205
67
|
align-items: center;
|
|
206
68
|
justify-content: center;
|
|
69
|
+
transition: background-color 0.2s ease;
|
|
207
70
|
}
|
|
208
71
|
.nav-toggle:hover {
|
|
209
|
-
background-color: rgba(
|
|
72
|
+
background-color: rgba(255,255,255,0.2);
|
|
210
73
|
}
|
|
211
74
|
.nav-toggle-icon {
|
|
212
75
|
width: 24px;
|
|
@@ -233,29 +96,42 @@
|
|
|
233
96
|
opacity: 1;
|
|
234
97
|
}
|
|
235
98
|
.nav-content {
|
|
236
|
-
padding: 0 0
|
|
99
|
+
padding: 0 0 20px 0;
|
|
237
100
|
transition: opacity 0.3s ease;
|
|
238
101
|
}
|
|
239
102
|
.collapsed .nav-content {
|
|
240
103
|
opacity: 0;
|
|
241
104
|
}
|
|
242
|
-
.nav-
|
|
105
|
+
.nav-sections {
|
|
243
106
|
display: flex;
|
|
244
107
|
flex-wrap: wrap;
|
|
245
|
-
|
|
108
|
+
gap: 20px;
|
|
246
109
|
}
|
|
247
|
-
.nav-
|
|
110
|
+
.nav-section {
|
|
248
111
|
flex: 1;
|
|
249
|
-
min-width:
|
|
250
|
-
|
|
251
|
-
|
|
112
|
+
min-width: 280px;
|
|
113
|
+
}
|
|
114
|
+
.nav-section h3 {
|
|
115
|
+
color: white;
|
|
116
|
+
font-size: 1rem;
|
|
117
|
+
font-weight: 600;
|
|
118
|
+
margin: 0 0 12px 0;
|
|
119
|
+
padding-bottom: 8px;
|
|
120
|
+
border-bottom: 1px solid rgba(255,255,255,0.2);
|
|
121
|
+
}
|
|
122
|
+
.nav-group {
|
|
123
|
+
background: rgba(255,255,255,0.1);
|
|
124
|
+
border-radius: 8px;
|
|
125
|
+
padding: 12px;
|
|
126
|
+
margin-bottom: 12px;
|
|
252
127
|
}
|
|
253
128
|
.nav-group-title {
|
|
254
|
-
color: rgba(255,255,255,0.
|
|
255
|
-
font-size: 0.
|
|
256
|
-
margin: 0 0 5px 0;
|
|
257
|
-
text-transform: uppercase;
|
|
129
|
+
color: rgba(255,255,255,0.9);
|
|
130
|
+
font-size: 0.875rem;
|
|
258
131
|
font-weight: 500;
|
|
132
|
+
margin: 0 0 8px 0;
|
|
133
|
+
text-transform: uppercase;
|
|
134
|
+
letter-spacing: 0.5px;
|
|
259
135
|
}
|
|
260
136
|
.nav-group-links {
|
|
261
137
|
list-style: none;
|
|
@@ -263,37 +139,348 @@
|
|
|
263
139
|
padding: 0;
|
|
264
140
|
}
|
|
265
141
|
.nav-group-links li {
|
|
266
|
-
margin:
|
|
142
|
+
margin: 6px 0;
|
|
267
143
|
}
|
|
268
144
|
.nav-group-links a {
|
|
269
145
|
color: white;
|
|
270
146
|
text-decoration: none;
|
|
271
|
-
font-weight:
|
|
272
|
-
padding:
|
|
147
|
+
font-weight: 500;
|
|
148
|
+
padding: 6px 8px;
|
|
273
149
|
display: inline-block;
|
|
150
|
+
border-radius: 4px;
|
|
151
|
+
transition: background-color 0.2s ease;
|
|
274
152
|
}
|
|
275
153
|
.nav-group-links a:hover {
|
|
276
|
-
|
|
154
|
+
background-color: rgba(255,255,255,0.2);
|
|
277
155
|
}
|
|
278
156
|
.nav-group-links .active {
|
|
279
|
-
|
|
157
|
+
background-color: rgba(255,255,255,0.2);
|
|
158
|
+
font-weight: 600;
|
|
280
159
|
}
|
|
281
160
|
.nav-group-links .disabled {
|
|
282
161
|
color: rgba(255,255,255,0.5);
|
|
283
162
|
cursor: not-allowed;
|
|
163
|
+
opacity: 0.7;
|
|
284
164
|
}
|
|
285
165
|
|
|
286
166
|
@media (max-width: 768px) {
|
|
287
|
-
.nav-
|
|
288
|
-
|
|
167
|
+
.nav-container {
|
|
168
|
+
padding: 0 16px;
|
|
169
|
+
}
|
|
170
|
+
.nav-title {
|
|
171
|
+
font-size: 1.125rem;
|
|
289
172
|
}
|
|
290
173
|
.nav-title-hint {
|
|
291
174
|
display: none;
|
|
292
175
|
}
|
|
176
|
+
.nav-sections {
|
|
177
|
+
flex-direction: column;
|
|
178
|
+
gap: 16px;
|
|
179
|
+
}
|
|
180
|
+
.nav-section {
|
|
181
|
+
min-width: 100%;
|
|
182
|
+
}
|
|
183
|
+
.nav-section h3 {
|
|
184
|
+
font-size: 0.875rem;
|
|
185
|
+
}
|
|
186
|
+
.nav-group {
|
|
187
|
+
padding: 10px;
|
|
188
|
+
}
|
|
189
|
+
.nav-group-title {
|
|
190
|
+
font-size: 0.8125rem;
|
|
191
|
+
}
|
|
192
|
+
.nav-group-links a {
|
|
193
|
+
padding: 8px 10px;
|
|
194
|
+
width: 100%;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
@media (max-width: 480px) {
|
|
199
|
+
.nav-topbar {
|
|
200
|
+
max-height: 60px;
|
|
201
|
+
}
|
|
202
|
+
.nav-topbar.collapsed {
|
|
203
|
+
max-height: 60px;
|
|
204
|
+
}
|
|
205
|
+
.nav-title {
|
|
206
|
+
font-size: 1rem;
|
|
207
|
+
}
|
|
208
|
+
.nav-toggle {
|
|
209
|
+
padding: 6px 10px;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.nav-group-dropdown {
|
|
214
|
+
position: relative;
|
|
215
|
+
display: inline-block;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.nav-group-dropdown-btn {
|
|
219
|
+
background: none;
|
|
220
|
+
border: none;
|
|
221
|
+
color: white;
|
|
222
|
+
font-weight: 500;
|
|
223
|
+
padding: 6px 8px;
|
|
224
|
+
cursor: pointer;
|
|
225
|
+
display: flex;
|
|
226
|
+
align-items: center;
|
|
227
|
+
gap: 4px;
|
|
228
|
+
border-radius: 4px;
|
|
229
|
+
transition: background-color 0.2s ease;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.nav-group-dropdown-btn:hover {
|
|
233
|
+
background-color: rgba(255,255,255,0.2);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.nav-group-dropdown-btn svg {
|
|
237
|
+
width: 16px;
|
|
238
|
+
height: 16px;
|
|
239
|
+
transition: transform 0.2s ease;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.nav-group-dropdown-btn.open svg {
|
|
243
|
+
transform: rotate(180deg);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.nav-group-dropdown-content {
|
|
247
|
+
display: none;
|
|
248
|
+
position: absolute;
|
|
249
|
+
background-color: rgba(33, 150, 243, 0.95);
|
|
250
|
+
min-width: 160px;
|
|
251
|
+
box-shadow: 0 8px 16px rgba(0,0,0,0.2);
|
|
252
|
+
z-index: 1;
|
|
253
|
+
border-radius: 4px;
|
|
254
|
+
padding: 8px 0;
|
|
255
|
+
margin-top: 4px;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.nav-group-dropdown-btn.open + .nav-group-dropdown-content {
|
|
259
|
+
display: block;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.nav-group-dropdown-content a {
|
|
263
|
+
color: white;
|
|
264
|
+
padding: 8px 16px;
|
|
265
|
+
text-decoration: none;
|
|
266
|
+
display: block;
|
|
267
|
+
transition: background-color 0.2s ease;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.nav-group-dropdown-content a:hover {
|
|
271
|
+
background-color: rgba(255,255,255,0.2);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.nav-group-dropdown-content a.active {
|
|
275
|
+
background-color: rgba(255,255,255,0.2);
|
|
276
|
+
font-weight: 600;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
@media (max-width: 768px) {
|
|
280
|
+
.nav-group-dropdown-content {
|
|
281
|
+
position: static;
|
|
282
|
+
box-shadow: none;
|
|
283
|
+
background-color: rgba(255,255,255,0.1);
|
|
284
|
+
margin-top: 8px;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
</style>
|
|
288
|
+
<script type="module" crossorigin src="/assets/invisible-frictionless-explicit-DugBtRe4.js"></script>
|
|
289
|
+
<link rel="modulepreload" crossorigin href="/assets/captcha-ByKnSsbG.js">
|
|
290
|
+
<link rel="stylesheet" crossorigin href="/assets/captcha-BhkVCEXM.css">
|
|
291
|
+
|
|
292
|
+
<style>
|
|
293
|
+
.form-filler-button {
|
|
294
|
+
position: fixed;
|
|
295
|
+
bottom: 20px;
|
|
296
|
+
right: 20px;
|
|
297
|
+
background-color: #2196F3;
|
|
298
|
+
color: white;
|
|
299
|
+
border: none;
|
|
300
|
+
border-radius: 30px;
|
|
301
|
+
padding: 12px 20px;
|
|
302
|
+
font-size: 14px;
|
|
303
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
|
304
|
+
cursor: pointer;
|
|
305
|
+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
|
306
|
+
z-index: 9999;
|
|
307
|
+
display: flex;
|
|
308
|
+
align-items: center;
|
|
309
|
+
gap: 8px;
|
|
310
|
+
transition: all 0.2s ease;
|
|
311
|
+
outline: none;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.form-filler-button:hover {
|
|
315
|
+
background-color: #1976D2;
|
|
316
|
+
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.25);
|
|
317
|
+
transform: translateY(-2px);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.form-filler-button:active {
|
|
321
|
+
transform: translateY(1px);
|
|
322
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.form-filler-button svg {
|
|
326
|
+
width: 18px;
|
|
327
|
+
height: 18px;
|
|
328
|
+
fill: white;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.form-filler-button span {
|
|
332
|
+
font-weight: 500;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
@media (max-width: 768px) {
|
|
336
|
+
.form-filler-button {
|
|
337
|
+
bottom: 15px;
|
|
338
|
+
right: 15px;
|
|
339
|
+
padding: 10px 15px;
|
|
340
|
+
font-size: 12px;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.form-filler-button svg {
|
|
344
|
+
width: 14px;
|
|
345
|
+
height: 14px;
|
|
346
|
+
}
|
|
293
347
|
}
|
|
294
348
|
</style>
|
|
295
|
-
|
|
296
|
-
|
|
349
|
+
|
|
350
|
+
<style>
|
|
351
|
+
.captcha-status {
|
|
352
|
+
margin-top: 20px;
|
|
353
|
+
padding: 15px;
|
|
354
|
+
background-color: #f0f8ff;
|
|
355
|
+
border: 2px solid #2196F3;
|
|
356
|
+
border-radius: 5px;
|
|
357
|
+
font-family: monospace;
|
|
358
|
+
font-size: 14px;
|
|
359
|
+
}
|
|
360
|
+
.status-item {
|
|
361
|
+
margin: 5px 0;
|
|
362
|
+
padding: 5px;
|
|
363
|
+
}
|
|
364
|
+
.status-success {
|
|
365
|
+
color: #4CAF50;
|
|
366
|
+
font-weight: bold;
|
|
367
|
+
}
|
|
368
|
+
.status-error {
|
|
369
|
+
color: #F44336;
|
|
370
|
+
font-weight: bold;
|
|
371
|
+
}
|
|
372
|
+
.status-info {
|
|
373
|
+
color: #2196F3;
|
|
374
|
+
}
|
|
375
|
+
.status-warning {
|
|
376
|
+
color: #FF9800;
|
|
377
|
+
}
|
|
378
|
+
.status-title {
|
|
379
|
+
font-weight: bold;
|
|
380
|
+
margin-bottom: 10px;
|
|
381
|
+
border-bottom: 1px solid #2196F3;
|
|
382
|
+
padding-bottom: 5px;
|
|
383
|
+
}
|
|
384
|
+
.console-output {
|
|
385
|
+
margin-top: 20px;
|
|
386
|
+
padding: 10px;
|
|
387
|
+
background-color: #f5f5f5;
|
|
388
|
+
border: 1px solid #ddd;
|
|
389
|
+
border-radius: 4px;
|
|
390
|
+
font-family: monospace;
|
|
391
|
+
white-space: pre-wrap;
|
|
392
|
+
max-height: 200px;
|
|
393
|
+
overflow-y: auto;
|
|
394
|
+
}
|
|
395
|
+
</style>
|
|
396
|
+
|
|
397
|
+
<script type="module">
|
|
398
|
+
// Function to update CAPTCHA status display
|
|
399
|
+
function updateCaptchaStatus(message, type = 'info') {
|
|
400
|
+
const statusContainer = document.getElementById('captcha-status');
|
|
401
|
+
if (!statusContainer) return;
|
|
402
|
+
|
|
403
|
+
const timestamp = new Date().toLocaleTimeString();
|
|
404
|
+
const statusItem = document.createElement('div');
|
|
405
|
+
statusItem.className = `status-item status-${type}`;
|
|
406
|
+
statusItem.innerHTML = `[${timestamp}] ${message}`;
|
|
407
|
+
statusContainer.appendChild(statusItem);
|
|
408
|
+
|
|
409
|
+
// Also log to console
|
|
410
|
+
console.log(`CAPTCHA Status: ${message}`);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Make updateCaptchaStatus available globally
|
|
414
|
+
window.updateCaptchaStatus = updateCaptchaStatus;
|
|
415
|
+
|
|
416
|
+
// Override the original callbacks with enhanced versions that use status logging
|
|
417
|
+
const originalOnCaptchaFailed = window.onCaptchaFailed;
|
|
418
|
+
window.onCaptchaFailed = function() {
|
|
419
|
+
updateCaptchaStatus('Challenge failed - CAPTCHA verification could not be completed', 'error');
|
|
420
|
+
if (originalOnCaptchaFailed) originalOnCaptchaFailed();
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const originalOnCaptchaVerified = window.onCaptchaVerified;
|
|
424
|
+
window.onCaptchaVerified = function(output) {
|
|
425
|
+
updateCaptchaStatus('Challenge passed successfully!', 'success');
|
|
426
|
+
updateCaptchaStatus(`Token generated: ${output.substring(0, 15)}...`, 'success');
|
|
427
|
+
if (originalOnCaptchaVerified) originalOnCaptchaVerified(output);
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
const originalOnActionHandler = window.onActionHandler;
|
|
431
|
+
window.onActionHandler = function() {
|
|
432
|
+
const procaptchaElements = document.getElementsByName('procaptcha-response');
|
|
433
|
+
|
|
434
|
+
if (!procaptchaElements.length) {
|
|
435
|
+
updateCaptchaStatus('Error: No CAPTCHA response token found', 'error');
|
|
436
|
+
alert("Must complete captcha");
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
updateCaptchaStatus('Form submission initiated with valid CAPTCHA token', 'info');
|
|
441
|
+
if (originalOnActionHandler) originalOnActionHandler();
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
445
|
+
updateCaptchaStatus('Page loaded - Initializing CAPTCHA system', 'info');
|
|
446
|
+
|
|
447
|
+
// Monitor DOM for CAPTCHA initialization
|
|
448
|
+
const observer = new MutationObserver((mutations) => {
|
|
449
|
+
mutations.forEach((mutation) => {
|
|
450
|
+
if (mutation.addedNodes.length) {
|
|
451
|
+
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
|
452
|
+
const node = mutation.addedNodes[i];
|
|
453
|
+
if (node.classList && (node.classList.contains('procaptcha') ||
|
|
454
|
+
node.querySelector && node.querySelector('.procaptcha'))) {
|
|
455
|
+
updateCaptchaStatus('CAPTCHA DOM elements initialized', 'info');
|
|
456
|
+
observer.disconnect();
|
|
457
|
+
break;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// Create a method to show CAPTCHA execution events
|
|
468
|
+
document.addEventListener('procaptcha:execute', function(e) {
|
|
469
|
+
// Determine captcha type from the page URL
|
|
470
|
+
const url = window.location.pathname;
|
|
471
|
+
const isFrictionless = url.includes('frictionless');
|
|
472
|
+
const isImage = url.includes('image');
|
|
473
|
+
const isPow = url.includes('pow');
|
|
474
|
+
|
|
475
|
+
let captchaType = 'unknown';
|
|
476
|
+
if (isFrictionless) captchaType = 'frictionless';
|
|
477
|
+
else if (isImage) captchaType = 'image';
|
|
478
|
+
else if (isPow) captchaType = 'pow';
|
|
479
|
+
|
|
480
|
+
updateCaptchaStatus(`CAPTCHA execution started: type=${captchaType}`, 'info');
|
|
481
|
+
updateCaptchaStatus(`Container: ${e.detail.containerId}, timestamp: ${new Date(e.detail.timestamp).toLocaleTimeString()}`, 'info');
|
|
482
|
+
});
|
|
483
|
+
</script>
|
|
297
484
|
</head>
|
|
298
485
|
<body>
|
|
299
486
|
|
|
@@ -316,36 +503,36 @@
|
|
|
316
503
|
</button>
|
|
317
504
|
</div>
|
|
318
505
|
<div class="nav-content">
|
|
319
|
-
<div class="nav-
|
|
506
|
+
<div class="nav-sections">
|
|
320
507
|
|
|
321
508
|
<div class="nav-section">
|
|
322
|
-
<h3
|
|
509
|
+
<h3>Standard Captchas</h3>
|
|
323
510
|
<div class="nav-row">
|
|
324
511
|
|
|
325
512
|
<div class="nav-group">
|
|
326
513
|
<div class="nav-group-title">Image</div>
|
|
327
|
-
<
|
|
328
|
-
<
|
|
329
|
-
<
|
|
330
|
-
</
|
|
514
|
+
<div class="nav-group-links">
|
|
515
|
+
<a href="image-implicit.html">Implicit</a>
|
|
516
|
+
<a href="image-explicit.html">Explicit</a>
|
|
517
|
+
</div>
|
|
331
518
|
</div>
|
|
332
519
|
|
|
333
520
|
|
|
334
521
|
<div class="nav-group">
|
|
335
522
|
<div class="nav-group-title">Pow</div>
|
|
336
|
-
<
|
|
337
|
-
<
|
|
338
|
-
<
|
|
339
|
-
</
|
|
523
|
+
<div class="nav-group-links">
|
|
524
|
+
<a href="pow-implicit.html">Implicit</a>
|
|
525
|
+
<a href="pow-explicit.html">Explicit</a>
|
|
526
|
+
</div>
|
|
340
527
|
</div>
|
|
341
528
|
|
|
342
529
|
|
|
343
530
|
<div class="nav-group">
|
|
344
531
|
<div class="nav-group-title">Frictionless</div>
|
|
345
|
-
<
|
|
346
|
-
<
|
|
347
|
-
<
|
|
348
|
-
</
|
|
532
|
+
<div class="nav-group-links">
|
|
533
|
+
<a href="frictionless-implicit.html">Implicit</a>
|
|
534
|
+
<a href="frictionless-explicit.html">Explicit</a>
|
|
535
|
+
</div>
|
|
349
536
|
</div>
|
|
350
537
|
|
|
351
538
|
</div>
|
|
@@ -353,33 +540,33 @@
|
|
|
353
540
|
|
|
354
541
|
|
|
355
542
|
<div class="nav-section">
|
|
356
|
-
<h3
|
|
543
|
+
<h3>Invisible Captchas</h3>
|
|
357
544
|
<div class="nav-row">
|
|
358
545
|
|
|
359
546
|
<div class="nav-group">
|
|
360
547
|
<div class="nav-group-title">Image</div>
|
|
361
|
-
<
|
|
362
|
-
<
|
|
363
|
-
<
|
|
364
|
-
</
|
|
548
|
+
<div class="nav-group-links">
|
|
549
|
+
<a href="invisible-image-implicit.html">Implicit</a>
|
|
550
|
+
<a href="invisible-image-explicit.html">Explicit</a>
|
|
551
|
+
</div>
|
|
365
552
|
</div>
|
|
366
553
|
|
|
367
554
|
|
|
368
555
|
<div class="nav-group">
|
|
369
556
|
<div class="nav-group-title">Pow</div>
|
|
370
|
-
<
|
|
371
|
-
<
|
|
372
|
-
<
|
|
373
|
-
</
|
|
557
|
+
<div class="nav-group-links">
|
|
558
|
+
<a href="invisible-pow-implicit.html">Implicit</a>
|
|
559
|
+
<a href="invisible-pow-explicit.html">Explicit</a>
|
|
560
|
+
</div>
|
|
374
561
|
</div>
|
|
375
562
|
|
|
376
563
|
|
|
377
564
|
<div class="nav-group">
|
|
378
565
|
<div class="nav-group-title">Frictionless</div>
|
|
379
|
-
<
|
|
380
|
-
<
|
|
381
|
-
<
|
|
382
|
-
</
|
|
566
|
+
<div class="nav-group-links">
|
|
567
|
+
<a href="invisible-frictionless-implicit.html">Implicit</a>
|
|
568
|
+
<a href="invisible-frictionless-explicit.html" class="active">Explicit</a>
|
|
569
|
+
</div>
|
|
383
570
|
</div>
|
|
384
571
|
|
|
385
572
|
</div>
|
|
@@ -390,90 +577,54 @@
|
|
|
390
577
|
</div>
|
|
391
578
|
</div>
|
|
392
579
|
|
|
393
|
-
<
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
<form id="demo-form" action="javascript:void(0);" method="POST">
|
|
397
|
-
<div>
|
|
398
|
-
<label for="name">Name:</label>
|
|
399
|
-
<input type="text" id="name" name="name" placeholder="Your name" required />
|
|
400
|
-
</div>
|
|
580
|
+
<div class="mui-container">
|
|
581
|
+
<h1>Procaptcha Frictionless Mode - Explicit Rendering</h1>
|
|
582
|
+
<p>This example demonstrates how to use Procaptcha in frictionless mode with explicit rendering.</p>
|
|
401
583
|
|
|
402
|
-
|
|
403
|
-
<label for="email">Email:</label>
|
|
404
|
-
<input type="email" id="email" name="email" placeholder="Your email" required />
|
|
405
|
-
</div>
|
|
584
|
+
<!-- Status log will be injected by the status-log-injector plugin -->
|
|
406
585
|
|
|
407
|
-
|
|
408
|
-
|
|
586
|
+
<form id="demo-form" class="mui-form">
|
|
587
|
+
<h2>Example Form</h2>
|
|
588
|
+
|
|
589
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
590
|
+
<label for="name">Name</label>
|
|
591
|
+
<input type="text" id="name" name="name" required />
|
|
592
|
+
</div>
|
|
593
|
+
|
|
594
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
595
|
+
<label for="email">Email</label>
|
|
596
|
+
<input type="email" id="email" name="email" required />
|
|
597
|
+
</div>
|
|
598
|
+
|
|
599
|
+
<!-- The container for the CAPTCHA -->
|
|
600
|
+
<div id="procaptcha-container"></div>
|
|
601
|
+
|
|
602
|
+
<button type="submit" class="mui-btn mui-btn--raised" data-cy="submit-button">Submit</button>
|
|
603
|
+
|
|
604
|
+
<div id="error"></div>
|
|
605
|
+
</form>
|
|
606
|
+
<!-- CAPTCHA Status Display -->
|
|
607
|
+
<div id="captcha-status" class="captcha-status">
|
|
608
|
+
<div class="status-title">CAPTCHA Status Log</div>
|
|
609
|
+
</div>
|
|
610
|
+
|
|
611
|
+
<!-- Console output display area -->
|
|
612
|
+
<div id="console-output" class="console-output" style="display: none;"></div>
|
|
613
|
+
|
|
409
614
|
|
|
410
|
-
|
|
411
|
-
<button id="submit-button" type="button">Submit</button>
|
|
412
|
-
</form>
|
|
413
|
-
|
|
414
|
-
<!-- Result display area -->
|
|
415
|
-
<div id="result"></div>
|
|
416
|
-
|
|
417
|
-
<!-- Console output display area -->
|
|
418
|
-
<div id="console-output" class="console-output" style="display: none;"></div>
|
|
419
|
-
|
|
420
|
-
<div style="margin-top: 20px;">
|
|
421
|
-
<h2>How It Works</h2>
|
|
422
|
-
<p>This example demonstrates how to use Procaptcha in invisible mode with explicit rendering:</p>
|
|
423
|
-
<ol>
|
|
424
|
-
<li>Include the Procaptcha script with <code>?render=explicit</code> parameter</li>
|
|
425
|
-
<li>Create a container div with <code>data-size="invisible"</code></li>
|
|
426
|
-
<li>Define an <code>onloadCallback</code> function that renders the Procaptcha widget</li>
|
|
427
|
-
<li>Add a click handler to your submit button that validates the form and executes Procaptcha</li>
|
|
428
|
-
<li>When Procaptcha verification succeeds, your callback function is called</li>
|
|
429
|
-
</ol>
|
|
430
|
-
<p>The key elements are:</p>
|
|
431
|
-
<pre>
|
|
432
|
-
<script type="module" src="./assets/procaptcha.bundle.js?render=explicit" async defer></script>
|
|
433
|
-
|
|
434
|
-
<div id="procaptcha-container" data-size="invisible"></div>
|
|
435
|
-
|
|
436
|
-
<script>
|
|
437
|
-
// Render the widget
|
|
438
|
-
window.procaptcha.render('procaptcha-container', {
|
|
439
|
-
'siteKey': 'your_site_key',
|
|
440
|
-
'callback': onSubmit,
|
|
441
|
-
'size': 'invisible'
|
|
442
|
-
});
|
|
615
|
+
<div id="result" class="info-box" style="display: none;"></div>
|
|
443
616
|
|
|
444
|
-
// Execute the verification
|
|
445
|
-
window.procaptcha.execute();
|
|
446
|
-
</script>
|
|
447
|
-
</pre>
|
|
448
617
|
|
|
449
|
-
|
|
450
|
-
<p>When you click the Submit button, the <code>execute()</code> function will:</p>
|
|
451
|
-
<ol>
|
|
452
|
-
<li>Find all Procaptcha containers on the page</li>
|
|
453
|
-
<li>Log each container and its attributes to the console</li>
|
|
454
|
-
<li>Log all child elements of each container</li>
|
|
455
|
-
<li>Dispatch a custom <code>procaptcha:execute</code> event to show the modal</li>
|
|
456
|
-
</ol>
|
|
457
|
-
<p>This helps debug and understand how the invisible Procaptcha is structured in the DOM.</p>
|
|
458
|
-
|
|
459
|
-
<h3>Event-Based Communication System</h3>
|
|
460
|
-
<p>To connect the vanilla JavaScript bundle with the React components, we use a custom event system:</p>
|
|
461
|
-
<ol>
|
|
462
|
-
<li>When <code>window.procaptcha.execute()</code> is called, it dispatches a <code>procaptcha:execute</code> event</li>
|
|
463
|
-
<li>The ProcaptchaWidget React component listens for this event</li>
|
|
464
|
-
<li>When the event is received, the component sets <code>state.showModal = true</code></li>
|
|
465
|
-
<li>This causes the CAPTCHA modal to appear and verification to begin</li>
|
|
466
|
-
</ol>
|
|
467
|
-
<p>This decoupled approach allows the JavaScript bundle to communicate with React components without direct references.</p>
|
|
618
|
+
<!-- Explanation will be injected by the explanation-injector plugin -->
|
|
468
619
|
</div>
|
|
469
620
|
|
|
470
|
-
<!-- Initialize Procaptcha with onload callback -->
|
|
471
621
|
|
|
472
622
|
<script>
|
|
473
623
|
document.addEventListener('DOMContentLoaded', function() {
|
|
474
624
|
const toggleBtn = document.getElementById('nav-toggle');
|
|
475
625
|
const navBar = document.getElementById('nav-topbar');
|
|
476
626
|
const navHeader = document.getElementById('nav-header');
|
|
627
|
+
const isMobile = window.innerWidth <= 768;
|
|
477
628
|
|
|
478
629
|
// Check if navigation was previously collapsed
|
|
479
630
|
const navCollapsed = localStorage.getItem('navCollapsed') === 'true';
|
|
@@ -505,20 +656,21 @@ window.procaptcha.execute();
|
|
|
505
656
|
|
|
506
657
|
// Toggle on button click
|
|
507
658
|
toggleBtn.addEventListener('click', function(e) {
|
|
508
|
-
e.stopPropagation();
|
|
659
|
+
e.stopPropagation();
|
|
509
660
|
toggleNav();
|
|
510
661
|
});
|
|
511
662
|
|
|
512
|
-
// Expand on toggle button hover when collapsed
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
663
|
+
// Expand on toggle button hover when collapsed (desktop only)
|
|
664
|
+
if (!isMobile) {
|
|
665
|
+
toggleBtn.addEventListener('mouseenter', function() {
|
|
666
|
+
if (navBar.classList.contains('collapsed')) {
|
|
667
|
+
expandNav();
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
}
|
|
518
671
|
|
|
519
672
|
// Toggle on header click
|
|
520
673
|
navHeader.addEventListener('click', function(e) {
|
|
521
|
-
// Don't toggle if a link within the header was clicked
|
|
522
674
|
if (e.target.tagName === 'A') {
|
|
523
675
|
return;
|
|
524
676
|
}
|
|
@@ -527,8 +679,199 @@ window.procaptcha.execute();
|
|
|
527
679
|
|
|
528
680
|
// Make the header appear clickable with cursor style
|
|
529
681
|
navHeader.style.cursor = 'pointer';
|
|
682
|
+
|
|
683
|
+
// Handle window resize
|
|
684
|
+
window.addEventListener('resize', function() {
|
|
685
|
+
const newIsMobile = window.innerWidth <= 768;
|
|
686
|
+
if (newIsMobile !== isMobile) {
|
|
687
|
+
if (newIsMobile) {
|
|
688
|
+
// On mobile, collapse the nav by default
|
|
689
|
+
collapseNav();
|
|
690
|
+
} else {
|
|
691
|
+
// On desktop, expand the nav by default
|
|
692
|
+
expandNav();
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
// Handle dropdown toggles
|
|
698
|
+
document.querySelectorAll('.nav-group-dropdown-btn').forEach(button => {
|
|
699
|
+
button.addEventListener('click', function(e) {
|
|
700
|
+
e.stopPropagation();
|
|
701
|
+
this.classList.toggle('open');
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
// Close dropdowns when clicking outside
|
|
706
|
+
document.addEventListener('click', function(e) {
|
|
707
|
+
if (!e.target.closest('.nav-group-dropdown')) {
|
|
708
|
+
document.querySelectorAll('.nav-group-dropdown-btn').forEach(button => {
|
|
709
|
+
button.classList.remove('open');
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
});
|
|
714
|
+
</script>
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
<button id="form-filler-button" class="form-filler-button" title="Fill all form fields with default values">
|
|
718
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
719
|
+
<path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/>
|
|
720
|
+
</svg>
|
|
721
|
+
<span>Fill Form</span>
|
|
722
|
+
</button>
|
|
723
|
+
|
|
724
|
+
<script>
|
|
725
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
726
|
+
// Create a function to fill the form with sensible default values
|
|
727
|
+
function fillFormWithDefaults() {
|
|
728
|
+
// Get all input elements
|
|
729
|
+
const inputs = document.querySelectorAll('input, select, textarea');
|
|
730
|
+
|
|
731
|
+
// Record which elements were filled for status feedback
|
|
732
|
+
const filledElements = [];
|
|
733
|
+
|
|
734
|
+
// Process each input
|
|
735
|
+
inputs.forEach(input => {
|
|
736
|
+
let filled = true;
|
|
737
|
+
|
|
738
|
+
// Skip hidden inputs and those with existing values
|
|
739
|
+
if (input.type === 'hidden' || (input.value && input.value.trim() !== '')) {
|
|
740
|
+
filled = false;
|
|
741
|
+
}
|
|
742
|
+
// Handle different input types
|
|
743
|
+
else if (input.type === 'text') {
|
|
744
|
+
if (input.id.toLowerCase().includes('name') || input.name.toLowerCase().includes('name')) {
|
|
745
|
+
input.value = 'John Doe';
|
|
746
|
+
} else {
|
|
747
|
+
input.value = 'Default Text';
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
else if (input.type === 'email') {
|
|
751
|
+
input.value = 'test@example.com';
|
|
752
|
+
}
|
|
753
|
+
else if (input.type === 'password') {
|
|
754
|
+
input.value = 'Password123!';
|
|
755
|
+
}
|
|
756
|
+
else if (input.type === 'tel') {
|
|
757
|
+
input.value = '+1234567890';
|
|
758
|
+
}
|
|
759
|
+
else if (input.type === 'number') {
|
|
760
|
+
input.value = '42';
|
|
761
|
+
}
|
|
762
|
+
else if (input.type === 'url') {
|
|
763
|
+
input.value = 'https://example.com';
|
|
764
|
+
}
|
|
765
|
+
else if (input.type === 'date') {
|
|
766
|
+
const today = new Date();
|
|
767
|
+
const yyyy = today.getFullYear();
|
|
768
|
+
const mm = String(today.getMonth() + 1).padStart(2, '0');
|
|
769
|
+
const dd = String(today.getDate()).padStart(2, '0');
|
|
770
|
+
input.value = `${yyyy}-${mm}-${dd}`;
|
|
771
|
+
}
|
|
772
|
+
else if (input.type === 'time') {
|
|
773
|
+
input.value = '12:00';
|
|
774
|
+
}
|
|
775
|
+
else if (input.type === 'checkbox' || input.type === 'radio') {
|
|
776
|
+
input.checked = true;
|
|
777
|
+
}
|
|
778
|
+
else if (input.tagName === 'SELECT') {
|
|
779
|
+
if (input.options.length > 0) {
|
|
780
|
+
input.selectedIndex = 1 >= input.options.length ? 0 : 1; // Select second option if available, first otherwise
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
else if (input.tagName === 'TEXTAREA') {
|
|
784
|
+
input.value = 'This is a sample text for the textarea field.';
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
// For any other input types
|
|
788
|
+
input.value = 'Default Value';
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// Add to filled elements if we actually filled it
|
|
792
|
+
if (filled) {
|
|
793
|
+
filledElements.push(input);
|
|
794
|
+
|
|
795
|
+
// Dispatch input event to trigger any listeners
|
|
796
|
+
const event = new Event('input', { bubbles: true });
|
|
797
|
+
input.dispatchEvent(event);
|
|
798
|
+
|
|
799
|
+
// For select elements, also dispatch change event
|
|
800
|
+
if (input.tagName === 'SELECT') {
|
|
801
|
+
const changeEvent = new Event('change', { bubbles: true });
|
|
802
|
+
input.dispatchEvent(changeEvent);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
// Show a notification about what was filled
|
|
808
|
+
if (filledElements.length > 0) {
|
|
809
|
+
// If an updateCaptchaStatus function exists (from our other demos), use it
|
|
810
|
+
if (typeof window.updateCaptchaStatus === 'function') {
|
|
811
|
+
window.updateCaptchaStatus(`Filled ${filledElements.length} form fields with default values`, 'info');
|
|
812
|
+
} else {
|
|
813
|
+
console.log(`Filled ${filledElements.length} form fields with default values`);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// Highlight the filled fields briefly
|
|
817
|
+
filledElements.forEach(el => {
|
|
818
|
+
const originalBackground = el.style.backgroundColor;
|
|
819
|
+
const originalTransition = el.style.transition;
|
|
820
|
+
|
|
821
|
+
el.style.transition = 'background-color 1.5s ease';
|
|
822
|
+
el.style.backgroundColor = '#e3f2fd';
|
|
823
|
+
|
|
824
|
+
setTimeout(() => {
|
|
825
|
+
el.style.backgroundColor = originalBackground;
|
|
826
|
+
setTimeout(() => {
|
|
827
|
+
el.style.transition = originalTransition;
|
|
828
|
+
}, 1500);
|
|
829
|
+
}, 500);
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// Add the click event listener to the form filler button
|
|
835
|
+
const formFillerButton = document.getElementById('form-filler-button');
|
|
836
|
+
if (formFillerButton) {
|
|
837
|
+
formFillerButton.addEventListener('click', fillFormWithDefaults);
|
|
838
|
+
}
|
|
530
839
|
});
|
|
531
840
|
</script>
|
|
532
841
|
|
|
533
|
-
|
|
842
|
+
<div class="explanation">
|
|
843
|
+
<h2>How Invisible Frictionless CAPTCHA Works (Explicit Rendering)</h2>
|
|
844
|
+
|
|
845
|
+
<h3>Implementation Details</h3>
|
|
846
|
+
<p>This example demonstrates how to use Procaptcha in frictionless mode with explicit rendering:</p>
|
|
847
|
+
<ol>
|
|
848
|
+
<li>Import the Procaptcha render function</li>
|
|
849
|
+
<li>Create a container for the CAPTCHA</li>
|
|
850
|
+
<li>Render the CAPTCHA explicitly</li>
|
|
851
|
+
<li>Handle the verification result in the callback function</li>
|
|
852
|
+
</ol>
|
|
853
|
+
|
|
854
|
+
<h3>Key Code Example</h3>
|
|
855
|
+
<pre>// Import the render function
|
|
856
|
+
import { render } from "%VITE_BUNDLE_URL%"
|
|
857
|
+
import { CaptchaType } from "@prosopo/types";
|
|
858
|
+
|
|
859
|
+
// Render CAPTCHA
|
|
860
|
+
const widgetId = render(document.getElementById('procaptcha-container'), {
|
|
861
|
+
siteKey: import.meta.env.PROSOPO_SITE_KEY_FRICTIONLESS,
|
|
862
|
+
captchaType: CaptchaType.frictionless,
|
|
863
|
+
callback: handleCaptchaResponse,
|
|
864
|
+
"failed-callback": handleCaptchaFailed,
|
|
865
|
+
size: "invisible"
|
|
866
|
+
});</pre>
|
|
867
|
+
|
|
868
|
+
<h3>Execution Flow</h3>
|
|
869
|
+
<ol>
|
|
870
|
+
<li>On page load, the render function is called to initialize</li>
|
|
871
|
+
<li>The CAPTCHA verification happens invisibly in the background</li>
|
|
872
|
+
<li>When verification is complete, the callback function is called with the token</li>
|
|
873
|
+
<li>On successful verification, the form can be submitted with the token</li>
|
|
874
|
+
</ol>
|
|
875
|
+
</div>
|
|
876
|
+
</body>
|
|
534
877
|
</html>
|