@prosopo/client-bundle-example 2.5.1 → 2.5.5

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.
@@ -0,0 +1,535 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Procaptcha Invisible Image Mode - Explicit Rendering</title>
5
+ <!-- Load the Procaptcha script with explicit rendering -->
6
+ <script type="module" src="https://staging-js.prosopo.io/js/procaptcha.bundle.js?render=explicit" async defer></script>
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': 'image',
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>
148
+
149
+ <style>
150
+ .nav-topbar {
151
+ background-color: #2196F3;
152
+ padding: 0;
153
+ margin-bottom: 20px;
154
+ transition: all 0.3s ease;
155
+ overflow: hidden;
156
+ max-height: 500px; /* Initial state - visible */
157
+ box-shadow: 0 2px 5px rgba(0,0,0,0.2);
158
+ }
159
+ .nav-topbar.collapsed {
160
+ max-height: 50px; /* Collapsed state - only show toggle button and title */
161
+ }
162
+ .nav-container {
163
+ max-width: 1200px;
164
+ margin: 0 auto;
165
+ padding: 0 15px;
166
+ position: relative;
167
+ }
168
+ .nav-header {
169
+ display: flex;
170
+ justify-content: space-between;
171
+ align-items: center;
172
+ padding: 10px 0;
173
+ position: relative;
174
+ z-index: 20;
175
+ }
176
+ .nav-title {
177
+ color: white;
178
+ font-size: 18px;
179
+ font-weight: bold;
180
+ margin: 0;
181
+ display: flex;
182
+ align-items: center;
183
+ }
184
+ .nav-title-text {
185
+ margin-right: 10px;
186
+ }
187
+ .nav-title-hint {
188
+ font-size: 14px;
189
+ font-weight: normal;
190
+ opacity: 0;
191
+ transition: opacity 0.3s ease;
192
+ }
193
+ .collapsed .nav-title-hint {
194
+ opacity: 0.8;
195
+ }
196
+ .nav-toggle {
197
+ background-color: rgba(0,0,0,0.1);
198
+ color: white;
199
+ border: none;
200
+ padding: 5px 10px;
201
+ cursor: pointer;
202
+ border-radius: 4px;
203
+ z-index: 10;
204
+ display: flex;
205
+ align-items: center;
206
+ justify-content: center;
207
+ }
208
+ .nav-toggle:hover {
209
+ background-color: rgba(0,0,0,0.2);
210
+ }
211
+ .nav-toggle-icon {
212
+ width: 24px;
213
+ height: 24px;
214
+ display: inline-block;
215
+ position: relative;
216
+ }
217
+ .nav-toggle-icon svg {
218
+ position: absolute;
219
+ top: 0;
220
+ left: 0;
221
+ transition: opacity 0.3s ease;
222
+ }
223
+ .nav-toggle-icon .icon-collapse {
224
+ opacity: 1;
225
+ }
226
+ .nav-toggle-icon .icon-expand {
227
+ opacity: 0;
228
+ }
229
+ .collapsed .nav-toggle-icon .icon-collapse {
230
+ opacity: 0;
231
+ }
232
+ .collapsed .nav-toggle-icon .icon-expand {
233
+ opacity: 1;
234
+ }
235
+ .nav-content {
236
+ padding: 0 0 15px 0;
237
+ transition: opacity 0.3s ease;
238
+ }
239
+ .collapsed .nav-content {
240
+ opacity: 0;
241
+ }
242
+ .nav-row {
243
+ display: flex;
244
+ flex-wrap: wrap;
245
+ margin-bottom: 15px;
246
+ }
247
+ .nav-group {
248
+ flex: 1;
249
+ min-width: 250px;
250
+ margin-bottom: 10px;
251
+ margin-right: 20px;
252
+ }
253
+ .nav-group-title {
254
+ color: rgba(255,255,255,0.8);
255
+ font-size: 0.9em;
256
+ margin: 0 0 5px 0;
257
+ text-transform: uppercase;
258
+ font-weight: 500;
259
+ }
260
+ .nav-group-links {
261
+ list-style: none;
262
+ margin: 0;
263
+ padding: 0;
264
+ }
265
+ .nav-group-links li {
266
+ margin: 5px 0;
267
+ }
268
+ .nav-group-links a {
269
+ color: white;
270
+ text-decoration: none;
271
+ font-weight: bold;
272
+ padding: 5px 0;
273
+ display: inline-block;
274
+ }
275
+ .nav-group-links a:hover {
276
+ text-decoration: underline;
277
+ }
278
+ .nav-group-links .active {
279
+ border-bottom: 2px solid white;
280
+ }
281
+ .nav-group-links .disabled {
282
+ color: rgba(255,255,255,0.5);
283
+ cursor: not-allowed;
284
+ }
285
+
286
+ @media (max-width: 768px) {
287
+ .nav-row {
288
+ flex-direction: column;
289
+ }
290
+ .nav-title-hint {
291
+ display: none;
292
+ }
293
+ }
294
+ </style>
295
+ <script type="module" crossorigin src="/assets/invisible-image-explicit-DgCaJtPg.js"></script>
296
+ <link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
297
+ </head>
298
+ <body>
299
+
300
+ <div id="nav-topbar" class="nav-topbar">
301
+ <div class="nav-container">
302
+ <div id="nav-header" class="nav-header">
303
+ <h1 class="nav-title">
304
+ <span class="nav-title-text">Procaptcha Demo Playground</span>
305
+ <span class="nav-title-hint">(Click anywhere to see more examples)</span>
306
+ </h1>
307
+ <button id="nav-toggle" class="nav-toggle" aria-label="Toggle navigation">
308
+ <span class="nav-toggle-icon">
309
+ <svg class="icon-collapse" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
310
+ <polyline points="18 15 12 9 6 15"></polyline>
311
+ </svg>
312
+ <svg class="icon-expand" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
313
+ <polyline points="6 9 12 15 18 9"></polyline>
314
+ </svg>
315
+ </span>
316
+ </button>
317
+ </div>
318
+ <div class="nav-content">
319
+ <div class="nav-row">
320
+
321
+ <div class="nav-section">
322
+ <h3 style="color: white; margin: 0 0 10px 0;">Standard Captchas</h3>
323
+ <div class="nav-row">
324
+
325
+ <div class="nav-group">
326
+ <div class="nav-group-title">Image</div>
327
+ <ul class="nav-group-links">
328
+ <li><a href="index.html">Implicit</a></li>
329
+ <li><span class="disabled" title="Coming Soon">Explicit</span></li>
330
+ </ul>
331
+ </div>
332
+
333
+
334
+ <div class="nav-group">
335
+ <div class="nav-group-title">Pow</div>
336
+ <ul class="nav-group-links">
337
+ <li><span class="disabled" title="Coming Soon">Implicit</span></li>
338
+ <li><span class="disabled" title="Coming Soon">Explicit</span></li>
339
+ </ul>
340
+ </div>
341
+
342
+
343
+ <div class="nav-group">
344
+ <div class="nav-group-title">Frictionless</div>
345
+ <ul class="nav-group-links">
346
+ <li><span class="disabled" title="Coming Soon">Implicit</span></li>
347
+ <li><a href="frictionless-explicit.html">Explicit</a></li>
348
+ </ul>
349
+ </div>
350
+
351
+ </div>
352
+ </div>
353
+
354
+
355
+ <div class="nav-section">
356
+ <h3 style="color: white; margin: 0 0 10px 0;">Invisible Captchas</h3>
357
+ <div class="nav-row">
358
+
359
+ <div class="nav-group">
360
+ <div class="nav-group-title">Image</div>
361
+ <ul class="nav-group-links">
362
+ <li><a href="invisible-image-implicit.html">Implicit</a></li>
363
+ <li><a href="invisible-image-explicit.html" class="active">Explicit</a></li>
364
+ </ul>
365
+ </div>
366
+
367
+
368
+ <div class="nav-group">
369
+ <div class="nav-group-title">Pow</div>
370
+ <ul class="nav-group-links">
371
+ <li><a href="invisible-pow-implicit.html">Implicit</a></li>
372
+ <li><a href="invisible-pow-explicit.html">Explicit</a></li>
373
+ </ul>
374
+ </div>
375
+
376
+
377
+ <div class="nav-group">
378
+ <div class="nav-group-title">Frictionless</div>
379
+ <ul class="nav-group-links">
380
+ <li><a href="invisible-frictionless-implicit.html">Implicit</a></li>
381
+ <li><a href="invisible-frictionless-explicit.html">Explicit</a></li>
382
+ </ul>
383
+ </div>
384
+
385
+ </div>
386
+ </div>
387
+
388
+ </div>
389
+ </div>
390
+ </div>
391
+ </div>
392
+
393
+ <h1>Procaptcha Invisible Image Mode</h1>
394
+ <p>This example demonstrates how to use Procaptcha in invisible image mode with explicit rendering.</p>
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>
401
+
402
+ <div>
403
+ <label for="email">Email:</label>
404
+ <input type="email" id="email" name="email" placeholder="Your email" required />
405
+ </div>
406
+
407
+ <!-- Invisible Procaptcha container -->
408
+ <div id="procaptcha-container" data-size="invisible"></div>
409
+
410
+ <!-- Regular submit button (not directly tied to Procaptcha) -->
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 image 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
+ &lt;script type="module" src="./assets/procaptcha.bundle.js?render=explicit" async defer&gt;&lt;/script&gt;
433
+
434
+ &lt;div id="procaptcha-container" data-size="invisible"&gt;&lt;/div&gt;
435
+
436
+ &lt;script&gt;
437
+ // Render the widget
438
+ window.procaptcha.render('procaptcha-container', {
439
+ 'siteKey': 'your_site_key',
440
+ 'callback': onSubmit,
441
+ 'size': 'invisible',
442
+ 'captchaType': 'image'
443
+ });
444
+
445
+ // Execute the verification
446
+ window.procaptcha.execute();
447
+ &lt;/script&gt;
448
+ </pre>
449
+
450
+ <h3>Console Output</h3>
451
+ <p>When you click the Submit button, the <code>execute()</code> function will:</p>
452
+ <ol>
453
+ <li>Find all Procaptcha containers on the page</li>
454
+ <li>Log each container and its attributes to the console</li>
455
+ <li>Log all child elements of each container</li>
456
+ <li>Dispatch a custom <code>procaptcha:execute</code> event to show the modal</li>
457
+ </ol>
458
+ <p>This helps debug and understand how the invisible Procaptcha is structured in the DOM.</p>
459
+
460
+ <h3>Event-Based Communication System</h3>
461
+ <p>To connect the vanilla JavaScript bundle with the React components, we use a custom event system:</p>
462
+ <ol>
463
+ <li>When <code>window.procaptcha.execute()</code> is called, it dispatches a <code>procaptcha:execute</code> event</li>
464
+ <li>The ProcaptchaWidget React component listens for this event</li>
465
+ <li>When the event is received, the component sets <code>state.showModal = true</code></li>
466
+ <li>This causes the CAPTCHA modal to appear and verification to begin</li>
467
+ </ol>
468
+ <p>This decoupled approach allows the JavaScript bundle to communicate with React components without direct references.</p>
469
+ </div>
470
+
471
+ <!-- Initialize Procaptcha with onload callback -->
472
+
473
+ <script>
474
+ document.addEventListener('DOMContentLoaded', function() {
475
+ const toggleBtn = document.getElementById('nav-toggle');
476
+ const navBar = document.getElementById('nav-topbar');
477
+ const navHeader = document.getElementById('nav-header');
478
+
479
+ // Check if navigation was previously collapsed
480
+ const navCollapsed = localStorage.getItem('navCollapsed') === 'true';
481
+ if (navCollapsed) {
482
+ navBar.classList.add('collapsed');
483
+ }
484
+
485
+ // Function to expand the navigation
486
+ function expandNav() {
487
+ if (navBar.classList.contains('collapsed')) {
488
+ navBar.classList.remove('collapsed');
489
+ localStorage.setItem('navCollapsed', 'false');
490
+ }
491
+ }
492
+
493
+ // Function to collapse the navigation
494
+ function collapseNav() {
495
+ if (!navBar.classList.contains('collapsed')) {
496
+ navBar.classList.add('collapsed');
497
+ localStorage.setItem('navCollapsed', 'true');
498
+ }
499
+ }
500
+
501
+ // Function to toggle the navigation
502
+ function toggleNav() {
503
+ navBar.classList.toggle('collapsed');
504
+ localStorage.setItem('navCollapsed', navBar.classList.contains('collapsed'));
505
+ }
506
+
507
+ // Toggle on button click
508
+ toggleBtn.addEventListener('click', function(e) {
509
+ e.stopPropagation(); // Prevent header click from firing
510
+ toggleNav();
511
+ });
512
+
513
+ // Expand on toggle button hover when collapsed
514
+ toggleBtn.addEventListener('mouseenter', function() {
515
+ if (navBar.classList.contains('collapsed')) {
516
+ expandNav();
517
+ }
518
+ });
519
+
520
+ // Toggle on header click
521
+ navHeader.addEventListener('click', function(e) {
522
+ // Don't toggle if a link within the header was clicked
523
+ if (e.target.tagName === 'A') {
524
+ return;
525
+ }
526
+ toggleNav();
527
+ });
528
+
529
+ // Make the header appear clickable with cursor style
530
+ navHeader.style.cursor = 'pointer';
531
+ });
532
+ </script>
533
+
534
+ </body>
535
+ </html>