@prosopo/client-bundle-example 2.10.12 → 2.10.18
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/.turbo/turbo-build$colon$cjs.log +6 -6
- package/.turbo/turbo-build$colon$tsc.log +14 -14
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +46 -0
- package/README.md +3 -1
- package/env.development +7 -0
- package/env.production +6 -0
- package/env.staging +2 -2
- package/package.json +10 -5
- package/src/assets/dummy.txt +0 -0
- package/src/frictionless-explicit-web3.html +249 -0
- package/src/frictionless-explicit.html +208 -0
- package/src/frictionless-implicit.html +218 -0
- package/src/image-explicit-web3.html +198 -0
- package/src/image-explicit.html +158 -0
- package/src/index.html +207 -0
- package/src/index.ts +76 -0
- package/src/invisible-frictionless-explicit.html +132 -0
- package/src/invisible-frictionless-implicit.html +204 -0
- package/src/invisible-image-explicit.html +161 -0
- package/src/invisible-image-implicit.html +203 -0
- package/src/invisible-pow-explicit.html +161 -0
- package/src/invisible-pow-implicit.html +106 -0
- package/src/invisible-puzzle-explicit.html +160 -0
- package/src/invisible-puzzle-implicit.html +106 -0
- package/src/plugins/explanation-injector.ts +294 -0
- package/src/plugins/form-filler-injector.ts +233 -0
- package/src/plugins/navigation-injector.ts +602 -0
- package/src/plugins/status-log-injector.ts +199 -0
- package/src/pow-explicit-web3.html +195 -0
- package/src/pow-explicit.html +158 -0
- package/src/pow-implicit.html +207 -0
- package/src/puzzle-explicit.html +158 -0
- package/src/puzzle-implicit.html +207 -0
- package/src/styles/captcha.css +78 -0
- package/src/styles/field.css +12 -0
- package/tsconfig.cjs.json +25 -0
- package/tsconfig.json +31 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsconfig.types.json +9 -0
- package/vite.cjs.config.ts +1 -1
- package/vite.config.ts +37 -4
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<link href="https://cdn.muicss.com/mui-0.10.3/css/mui.min.css" rel="stylesheet" type="text/css"/>
|
|
5
|
+
<link href="styles/field.css" rel="stylesheet" type="text/css"/>
|
|
6
|
+
|
|
7
|
+
<script src="index.js"></script>
|
|
8
|
+
<title>Procaptcha POW Mode - Explicit Rendering</title>
|
|
9
|
+
<link href="styles/captcha.css" rel="stylesheet" type="text/css"/>
|
|
10
|
+
<script type="module">
|
|
11
|
+
// Function to update CAPTCHA status display is now provided by status-log-injector
|
|
12
|
+
|
|
13
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
14
|
+
|
|
15
|
+
updateCaptchaStatus('Page loaded - Initializing CAPTCHA system', 'info');
|
|
16
|
+
|
|
17
|
+
// Monitor DOM for CAPTCHA initialization
|
|
18
|
+
const observer = new MutationObserver((mutations) => {
|
|
19
|
+
mutations.forEach((mutation) => {
|
|
20
|
+
if (mutation.addedNodes.length) {
|
|
21
|
+
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
|
22
|
+
const node = mutation.addedNodes[i];
|
|
23
|
+
if (node.classList && (node.classList.contains('procaptcha') ||
|
|
24
|
+
node.querySelector && node.querySelector('.procaptcha'))) {
|
|
25
|
+
updateCaptchaStatus('CAPTCHA DOM elements initialized', 'info');
|
|
26
|
+
observer.disconnect();
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// updateCaptchaStatus is now provided by status-log-injector
|
|
38
|
+
</script>
|
|
39
|
+
</head>
|
|
40
|
+
<body>
|
|
41
|
+
<div class="mui-container">
|
|
42
|
+
<h1>Procaptcha PoW Mode - Explicit Rendering</h1>
|
|
43
|
+
<p>This example demonstrates how to use Procaptcha in pow mode with explicit rendering.</p>
|
|
44
|
+
|
|
45
|
+
<!-- CAPTCHA Status Display will be injected by the status-log-injector plugin -->
|
|
46
|
+
|
|
47
|
+
<form id="demo-form" class="mui-form">
|
|
48
|
+
<h2>Example Form</h2>
|
|
49
|
+
|
|
50
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
51
|
+
<label for="name">Name</label>
|
|
52
|
+
<input type="text" id="name" name="name" required />
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
56
|
+
<label for="email">Email</label>
|
|
57
|
+
<input type="email" id="email" name="email" required />
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<!-- The container for the CAPTCHA -->
|
|
61
|
+
<div id="procaptcha-container"></div>
|
|
62
|
+
|
|
63
|
+
<button type="submit" class="mui-btn mui-btn--raised">Submit</button>
|
|
64
|
+
|
|
65
|
+
<div id="error"></div>
|
|
66
|
+
</form>
|
|
67
|
+
|
|
68
|
+
<div id="result" class="info-box" style="display: none;"></div>
|
|
69
|
+
|
|
70
|
+
<!-- Console output display area -->
|
|
71
|
+
<div id="console-output" class="console-output" style="display: none;"></div>
|
|
72
|
+
|
|
73
|
+
<!-- Explanation will be injected by the explanation-injector plugin -->
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<script type="module">
|
|
77
|
+
import { render, execute } from "%VITE_BUNDLE_URL%"
|
|
78
|
+
|
|
79
|
+
// Form validation function
|
|
80
|
+
function validateForm() {
|
|
81
|
+
const nameInput = document.getElementById('name');
|
|
82
|
+
const emailInput = document.getElementById('email');
|
|
83
|
+
const errorDisplay = document.getElementById('error');
|
|
84
|
+
|
|
85
|
+
if (!nameInput.value || !emailInput.value) {
|
|
86
|
+
errorDisplay.textContent = 'Please fill out all fields';
|
|
87
|
+
errorDisplay.style.display = 'block';
|
|
88
|
+
window.updateCaptchaStatus('Form validation failed: Empty fields', 'error');
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Basic email validation
|
|
93
|
+
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
94
|
+
if (!emailPattern.test(emailInput.value)) {
|
|
95
|
+
errorDisplay.textContent = 'Please enter a valid email address';
|
|
96
|
+
errorDisplay.style.display = 'block';
|
|
97
|
+
window.updateCaptchaStatus('Form validation failed: Invalid email format', 'error');
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
errorDisplay.style.display = 'none';
|
|
102
|
+
window.updateCaptchaStatus('Form validation passed', 'info');
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Callback for successful CAPTCHA verification
|
|
107
|
+
function handleCaptchaResponse(token) {
|
|
108
|
+
console.log('Procaptcha verified, token:', token);
|
|
109
|
+
window.updateCaptchaStatus('Challenge passed successfully!', 'success');
|
|
110
|
+
window.updateCaptchaStatus(`Token generated: ${token.substring(0, 15)}...`, 'success');
|
|
111
|
+
|
|
112
|
+
const name = document.getElementById('name').value;
|
|
113
|
+
const email = document.getElementById('email').value;
|
|
114
|
+
|
|
115
|
+
// Display result
|
|
116
|
+
const resultElement = document.getElementById('result');
|
|
117
|
+
resultElement.innerHTML = `<strong>Form submitted with:</strong><br>
|
|
118
|
+
- Name: ${name}<br>
|
|
119
|
+
- Email: ${email}<br>
|
|
120
|
+
- Procaptcha verified: Yes`;
|
|
121
|
+
resultElement.style.display = 'block';
|
|
122
|
+
|
|
123
|
+
window.updateCaptchaStatus('Form submission completed', 'success');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Callback for failed CAPTCHA verification
|
|
127
|
+
function handleCaptchaFailed() {
|
|
128
|
+
console.log('Captcha verification failed');
|
|
129
|
+
window.updateCaptchaStatus('Challenge failed - CAPTCHA verification could not be completed', 'error');
|
|
130
|
+
document.getElementById('error').textContent = 'CAPTCHA verification failed. Please try again.';
|
|
131
|
+
document.getElementById('error').style.display = 'block';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Wait for DOM content to be loaded
|
|
135
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
136
|
+
window.updateCaptchaStatus('Initializing CAPTCHA with explicit render call', 'info');
|
|
137
|
+
|
|
138
|
+
// Render the CAPTCHA
|
|
139
|
+
const widgetId = render(document.getElementById('procaptcha-container'), {
|
|
140
|
+
siteKey: import.meta.env.PROSOPO_SITE_KEY_POW,
|
|
141
|
+
callback: handleCaptchaResponse,
|
|
142
|
+
"failed-callback": handleCaptchaFailed,
|
|
143
|
+
size: "invisible"
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
window.updateCaptchaStatus('CAPTCHA render function called with widget ID: ' + widgetId, 'info');
|
|
147
|
+
|
|
148
|
+
// Add form submit handler
|
|
149
|
+
document.getElementById('demo-form').addEventListener('submit', function(e) {
|
|
150
|
+
e.preventDefault();
|
|
151
|
+
window.updateCaptchaStatus('Form submission attempted', 'info');
|
|
152
|
+
if (validateForm()) {
|
|
153
|
+
// Form is valid, CAPTCHA verification will be handled by the callback
|
|
154
|
+
window.updateCaptchaStatus('Waiting for CAPTCHA verification', 'info');
|
|
155
|
+
execute();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
</script>
|
|
160
|
+
</body>
|
|
161
|
+
</html>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<link href="https://cdn.muicss.com/mui-0.10.3/css/mui.min.css" rel="stylesheet" type="text/css"/>
|
|
5
|
+
<link href="styles/field.css" rel="stylesheet" type="text/css"/>
|
|
6
|
+
|
|
7
|
+
<script src="index.js"></script>
|
|
8
|
+
<title>Procaptcha Invisible POW Mode - Implicit Rendering</title>
|
|
9
|
+
<link href="styles/captcha.css" rel="stylesheet" type="text/css"/>
|
|
10
|
+
<script type="module">
|
|
11
|
+
// Function to update CAPTCHA status display is now provided by status-log-injector
|
|
12
|
+
|
|
13
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
14
|
+
updateCaptchaStatus('Page loaded - Initializing CAPTCHA system', 'info');
|
|
15
|
+
|
|
16
|
+
// Monitor DOM for CAPTCHA initialization
|
|
17
|
+
const observer = new MutationObserver((mutations) => {
|
|
18
|
+
mutations.forEach((mutation) => {
|
|
19
|
+
if (mutation.addedNodes.length) {
|
|
20
|
+
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
|
21
|
+
const node = mutation.addedNodes[i];
|
|
22
|
+
if (node.classList && (node.classList.contains('procaptcha') ||
|
|
23
|
+
node.querySelector && node.querySelector('.procaptcha'))) {
|
|
24
|
+
updateCaptchaStatus('CAPTCHA DOM elements initialized', 'info');
|
|
25
|
+
observer.disconnect();
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Create a method to show CAPTCHA execution events
|
|
37
|
+
document.addEventListener('procaptcha:execute', function(e) {
|
|
38
|
+
updateCaptchaStatus(`CAPTCHA execution started: type=pow, mode=invisible`, 'info');
|
|
39
|
+
updateCaptchaStatus(`Container: ${e.detail.containerId}, timestamp: ${new Date(e.detail.timestamp).toLocaleTimeString()}`, 'info');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
window.onSubmit = function(token) {
|
|
43
|
+
console.log('Procaptcha verified, token: ' + token);
|
|
44
|
+
updateCaptchaStatus('Challenge passed successfully!', 'success');
|
|
45
|
+
updateCaptchaStatus(`Token generated: ${token.substring(0, 15)}...`, 'success');
|
|
46
|
+
|
|
47
|
+
// Get form values
|
|
48
|
+
const name = document.getElementById('name').value;
|
|
49
|
+
const email = document.getElementById('email').value;
|
|
50
|
+
|
|
51
|
+
const resultElement = document.getElementById('result');
|
|
52
|
+
if (resultElement) {
|
|
53
|
+
resultElement.innerHTML = `<strong>Form submitted with:</strong><br>
|
|
54
|
+
- Name: ${name}<br>
|
|
55
|
+
- Email: ${email}<br>
|
|
56
|
+
- Procaptcha verified: Yes`;
|
|
57
|
+
resultElement.style.display = 'block';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
updateCaptchaStatus('Form submission completed', 'success');
|
|
61
|
+
|
|
62
|
+
// Prevent actual form submission
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
<!-- Load the Procaptcha script -->
|
|
67
|
+
<script type="module" src="%VITE_BUNDLE_URL%" async defer></script>
|
|
68
|
+
</head>
|
|
69
|
+
<body>
|
|
70
|
+
<div class="mui-container">
|
|
71
|
+
<h1>Invisible Proof of Work CAPTCHA - Implicit Rendering</h1>
|
|
72
|
+
<p>This example demonstrates how to use Procaptcha in invisible Proof of Work mode with implicit rendering directly on a button.</p>
|
|
73
|
+
|
|
74
|
+
<!-- CAPTCHA Status Display will be injected by the status-log-injector plugin -->
|
|
75
|
+
|
|
76
|
+
<form id="demo-form" action="javascript:void(0);" method="POST" class="mui-form">
|
|
77
|
+
<h2>Example Form</h2>
|
|
78
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
79
|
+
<label for="name">Name</label>
|
|
80
|
+
<input type="text" id="name" name="name" required />
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
84
|
+
<label for="email">Email</label>
|
|
85
|
+
<input type="email" id="email" name="email" required />
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<!-- Submit button with Procaptcha attributes -->
|
|
89
|
+
<button
|
|
90
|
+
class="mui-btn mui-btn--raised procaptcha"
|
|
91
|
+
data-sitekey="%PROSOPO_SITE_KEY_POW%"
|
|
92
|
+
data-callback="onSubmit"
|
|
93
|
+
data-size="invisible">
|
|
94
|
+
Submit
|
|
95
|
+
</button>
|
|
96
|
+
</form>
|
|
97
|
+
|
|
98
|
+
<div id="result" class="info-box" style="display: none;"></div>
|
|
99
|
+
|
|
100
|
+
<!-- Console output display area -->
|
|
101
|
+
<div id="console-output" class="console-output" style="display: none;"></div>
|
|
102
|
+
|
|
103
|
+
<!-- Explanation will be injected by the explanation-injector plugin -->
|
|
104
|
+
</div>
|
|
105
|
+
</body>
|
|
106
|
+
</html>
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<link href="https://cdn.muicss.com/mui-0.10.3/css/mui.min.css" rel="stylesheet" type="text/css"/>
|
|
5
|
+
<link href="styles/field.css" rel="stylesheet" type="text/css"/>
|
|
6
|
+
|
|
7
|
+
<script src="index.js"></script>
|
|
8
|
+
<title>Procaptcha Invisible Puzzle Mode - Explicit Rendering</title>
|
|
9
|
+
<link href="styles/captcha.css" rel="stylesheet" type="text/css"/>
|
|
10
|
+
<script type="module">
|
|
11
|
+
// Function to update CAPTCHA status display is now provided by status-log-injector
|
|
12
|
+
|
|
13
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
14
|
+
|
|
15
|
+
updateCaptchaStatus('Page loaded - Initializing CAPTCHA system', 'info');
|
|
16
|
+
|
|
17
|
+
// Monitor DOM for CAPTCHA initialization
|
|
18
|
+
const observer = new MutationObserver((mutations) => {
|
|
19
|
+
mutations.forEach((mutation) => {
|
|
20
|
+
if (mutation.addedNodes.length) {
|
|
21
|
+
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
|
22
|
+
const node = mutation.addedNodes[i];
|
|
23
|
+
if (node.classList && (node.classList.contains('procaptcha') ||
|
|
24
|
+
node.querySelector && node.querySelector('.procaptcha'))) {
|
|
25
|
+
updateCaptchaStatus('CAPTCHA DOM elements initialized', 'info');
|
|
26
|
+
observer.disconnect();
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// updateCaptchaStatus is now provided by status-log-injector
|
|
38
|
+
</script>
|
|
39
|
+
</head>
|
|
40
|
+
<body>
|
|
41
|
+
<div class="mui-container">
|
|
42
|
+
<h1>Procaptcha Invisible Puzzle Mode - Explicit Rendering</h1>
|
|
43
|
+
<p>This example demonstrates how to use Procaptcha in invisible Puzzle mode with explicit rendering. The puzzle overlay appears after the form is submitted.</p>
|
|
44
|
+
|
|
45
|
+
<!-- CAPTCHA Status Display will be injected by the status-log-injector plugin -->
|
|
46
|
+
|
|
47
|
+
<form id="demo-form" class="mui-form">
|
|
48
|
+
<h2>Example Form</h2>
|
|
49
|
+
|
|
50
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
51
|
+
<label for="name">Name</label>
|
|
52
|
+
<input type="text" id="name" name="name" required />
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
56
|
+
<label for="email">Email</label>
|
|
57
|
+
<input type="email" id="email" name="email" required />
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<!-- The container for the CAPTCHA -->
|
|
61
|
+
<div id="procaptcha-container"></div>
|
|
62
|
+
|
|
63
|
+
<button type="submit" class="mui-btn mui-btn--raised">Submit</button>
|
|
64
|
+
|
|
65
|
+
<div id="error"></div>
|
|
66
|
+
</form>
|
|
67
|
+
|
|
68
|
+
<div id="result" class="info-box" style="display: none;"></div>
|
|
69
|
+
|
|
70
|
+
<!-- Console output display area -->
|
|
71
|
+
<div id="console-output" class="console-output" style="display: none;"></div>
|
|
72
|
+
|
|
73
|
+
<!-- Explanation will be injected by the explanation-injector plugin -->
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<script type="module">
|
|
77
|
+
import { render, execute } from "%VITE_BUNDLE_URL%"
|
|
78
|
+
|
|
79
|
+
// Form validation function
|
|
80
|
+
function validateForm() {
|
|
81
|
+
const nameInput = document.getElementById('name');
|
|
82
|
+
const emailInput = document.getElementById('email');
|
|
83
|
+
const errorDisplay = document.getElementById('error');
|
|
84
|
+
|
|
85
|
+
if (!nameInput.value || !emailInput.value) {
|
|
86
|
+
errorDisplay.textContent = 'Please fill out all fields';
|
|
87
|
+
errorDisplay.style.display = 'block';
|
|
88
|
+
window.updateCaptchaStatus('Form validation failed: Empty fields', 'error');
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Basic email validation
|
|
93
|
+
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
94
|
+
if (!emailPattern.test(emailInput.value)) {
|
|
95
|
+
errorDisplay.textContent = 'Please enter a valid email address';
|
|
96
|
+
errorDisplay.style.display = 'block';
|
|
97
|
+
window.updateCaptchaStatus('Form validation failed: Invalid email format', 'error');
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
errorDisplay.style.display = 'none';
|
|
102
|
+
window.updateCaptchaStatus('Form validation passed', 'info');
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Callback for successful CAPTCHA verification
|
|
107
|
+
function handleCaptchaResponse(token) {
|
|
108
|
+
console.log('Procaptcha verified, token:', token);
|
|
109
|
+
window.updateCaptchaStatus('Challenge passed successfully!', 'success');
|
|
110
|
+
window.updateCaptchaStatus(`Token generated: ${token.substring(0, 15)}...`, 'success');
|
|
111
|
+
|
|
112
|
+
const name = document.getElementById('name').value;
|
|
113
|
+
const email = document.getElementById('email').value;
|
|
114
|
+
|
|
115
|
+
// Display result. textContent (not innerHTML) — user-typed values
|
|
116
|
+
// must not be interpreted as HTML; whitespace preserved via CSS.
|
|
117
|
+
const resultElement = document.getElementById('result');
|
|
118
|
+
resultElement.textContent = `Form submitted with:\n- Name: ${name}\n- Email: ${email}\n- Procaptcha verified: Yes`;
|
|
119
|
+
resultElement.style.whiteSpace = 'pre-wrap';
|
|
120
|
+
resultElement.style.display = 'block';
|
|
121
|
+
|
|
122
|
+
window.updateCaptchaStatus('Form submission completed', 'success');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Callback for failed CAPTCHA verification
|
|
126
|
+
function handleCaptchaFailed() {
|
|
127
|
+
console.log('Captcha verification failed');
|
|
128
|
+
window.updateCaptchaStatus('Challenge failed - CAPTCHA verification could not be completed', 'error');
|
|
129
|
+
document.getElementById('error').textContent = 'CAPTCHA verification failed. Please try again.';
|
|
130
|
+
document.getElementById('error').style.display = 'block';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Wait for DOM content to be loaded
|
|
134
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
135
|
+
window.updateCaptchaStatus('Initializing CAPTCHA with explicit render call', 'info');
|
|
136
|
+
|
|
137
|
+
// Render the CAPTCHA
|
|
138
|
+
const widgetId = render(document.getElementById('procaptcha-container'), {
|
|
139
|
+
siteKey: import.meta.env.PROSOPO_SITE_KEY_PUZZLE,
|
|
140
|
+
callback: handleCaptchaResponse,
|
|
141
|
+
"failed-callback": handleCaptchaFailed,
|
|
142
|
+
size: "invisible"
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
window.updateCaptchaStatus('CAPTCHA render function called with widget ID: ' + widgetId, 'info');
|
|
146
|
+
|
|
147
|
+
// Add form submit handler
|
|
148
|
+
document.getElementById('demo-form').addEventListener('submit', function(e) {
|
|
149
|
+
e.preventDefault();
|
|
150
|
+
window.updateCaptchaStatus('Form submission attempted', 'info');
|
|
151
|
+
if (validateForm()) {
|
|
152
|
+
// Form is valid, CAPTCHA verification will be handled by the callback
|
|
153
|
+
window.updateCaptchaStatus('Waiting for CAPTCHA verification', 'info');
|
|
154
|
+
execute();
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
</script>
|
|
159
|
+
</body>
|
|
160
|
+
</html>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<link href="https://cdn.muicss.com/mui-0.10.3/css/mui.min.css" rel="stylesheet" type="text/css"/>
|
|
5
|
+
<link href="styles/field.css" rel="stylesheet" type="text/css"/>
|
|
6
|
+
|
|
7
|
+
<script src="index.js"></script>
|
|
8
|
+
<title>Procaptcha Invisible Puzzle Mode - Implicit Rendering</title>
|
|
9
|
+
<link href="styles/captcha.css" rel="stylesheet" type="text/css"/>
|
|
10
|
+
<script type="module">
|
|
11
|
+
// Function to update CAPTCHA status display is now provided by status-log-injector
|
|
12
|
+
|
|
13
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
14
|
+
updateCaptchaStatus('Page loaded - Initializing CAPTCHA system', 'info');
|
|
15
|
+
|
|
16
|
+
// Monitor DOM for CAPTCHA initialization
|
|
17
|
+
const observer = new MutationObserver((mutations) => {
|
|
18
|
+
mutations.forEach((mutation) => {
|
|
19
|
+
if (mutation.addedNodes.length) {
|
|
20
|
+
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
|
21
|
+
const node = mutation.addedNodes[i];
|
|
22
|
+
if (node.classList && (node.classList.contains('procaptcha') ||
|
|
23
|
+
node.querySelector && node.querySelector('.procaptcha'))) {
|
|
24
|
+
updateCaptchaStatus('CAPTCHA DOM elements initialized', 'info');
|
|
25
|
+
observer.disconnect();
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Create a method to show CAPTCHA execution events
|
|
37
|
+
document.addEventListener('procaptcha:execute', function(e) {
|
|
38
|
+
updateCaptchaStatus(`CAPTCHA execution started: type=puzzle, mode=invisible`, 'info');
|
|
39
|
+
updateCaptchaStatus(`Container: ${e.detail.containerId}, timestamp: ${new Date(e.detail.timestamp).toLocaleTimeString()}`, 'info');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
window.onSubmit = function(token) {
|
|
43
|
+
console.log('Procaptcha verified, token: ' + token);
|
|
44
|
+
updateCaptchaStatus('Challenge passed successfully!', 'success');
|
|
45
|
+
updateCaptchaStatus(`Token generated: ${token.substring(0, 15)}...`, 'success');
|
|
46
|
+
|
|
47
|
+
// Get form values
|
|
48
|
+
const name = document.getElementById('name').value;
|
|
49
|
+
const email = document.getElementById('email').value;
|
|
50
|
+
|
|
51
|
+
const resultElement = document.getElementById('result');
|
|
52
|
+
if (resultElement) {
|
|
53
|
+
// textContent (not innerHTML) — user-typed values must not be
|
|
54
|
+
// interpreted as HTML; whitespace preserved via CSS below.
|
|
55
|
+
resultElement.textContent = `Form submitted with:\n- Name: ${name}\n- Email: ${email}\n- Procaptcha verified: Yes`;
|
|
56
|
+
resultElement.style.whiteSpace = 'pre-wrap';
|
|
57
|
+
resultElement.style.display = 'block';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
updateCaptchaStatus('Form submission completed', 'success');
|
|
61
|
+
|
|
62
|
+
// Prevent actual form submission
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
<!-- Load the Procaptcha script -->
|
|
67
|
+
<script type="module" src="%VITE_BUNDLE_URL%" async defer></script>
|
|
68
|
+
</head>
|
|
69
|
+
<body>
|
|
70
|
+
<div class="mui-container">
|
|
71
|
+
<h1>Invisible Puzzle CAPTCHA - Implicit Rendering</h1>
|
|
72
|
+
<p>This example demonstrates how to use Procaptcha in invisible Puzzle mode with implicit rendering directly on a button. The puzzle overlay appears when the button is clicked.</p>
|
|
73
|
+
|
|
74
|
+
<!-- CAPTCHA Status Display will be injected by the status-log-injector plugin -->
|
|
75
|
+
|
|
76
|
+
<form id="demo-form" action="javascript:void(0);" method="POST" class="mui-form">
|
|
77
|
+
<h2>Example Form</h2>
|
|
78
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
79
|
+
<label for="name">Name</label>
|
|
80
|
+
<input type="text" id="name" name="name" required />
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
84
|
+
<label for="email">Email</label>
|
|
85
|
+
<input type="email" id="email" name="email" required />
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<!-- Submit button with Procaptcha attributes -->
|
|
89
|
+
<button
|
|
90
|
+
class="mui-btn mui-btn--raised procaptcha"
|
|
91
|
+
data-sitekey="%PROSOPO_SITE_KEY_PUZZLE%"
|
|
92
|
+
data-callback="onSubmit"
|
|
93
|
+
data-size="invisible">
|
|
94
|
+
Submit
|
|
95
|
+
</button>
|
|
96
|
+
</form>
|
|
97
|
+
|
|
98
|
+
<div id="result" class="info-box" style="display: none;"></div>
|
|
99
|
+
|
|
100
|
+
<!-- Console output display area -->
|
|
101
|
+
<div id="console-output" class="console-output" style="display: none;"></div>
|
|
102
|
+
|
|
103
|
+
<!-- Explanation will be injected by the explanation-injector plugin -->
|
|
104
|
+
</div>
|
|
105
|
+
</body>
|
|
106
|
+
</html>
|