@prosopo/client-bundle-example 2.11.3 → 2.11.4

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.
Files changed (53) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +4 -7
  2. package/.turbo/turbo-build$colon$tsc.log +11 -14
  3. package/.turbo/turbo-build.log +4 -10
  4. package/CHANGELOG.md +27 -0
  5. package/LICENSE +201 -0
  6. package/README.md +6 -6
  7. package/dist/cjs/plugins/pages.cjs +7 -0
  8. package/dist/plugins/pages.js +7 -0
  9. package/env.staging +5 -4
  10. package/package.json +52 -53
  11. package/vite.config.ts +50 -1
  12. package/env.development +0 -7
  13. package/env.production +0 -6
  14. package/src/assets/dummy.txt +0 -0
  15. package/src/frictionless-explicit-web3.html +0 -237
  16. package/src/frictionless-explicit.html +0 -205
  17. package/src/frictionless-implicit.html +0 -192
  18. package/src/frictionless-manual-start.html +0 -204
  19. package/src/image-explicit-web3.html +0 -182
  20. package/src/image-explicit.html +0 -151
  21. package/src/image-implicit.html +0 -192
  22. package/src/index.html +0 -192
  23. package/src/index.ts +0 -15
  24. package/src/invisible-frictionless-explicit.html +0 -123
  25. package/src/invisible-frictionless-implicit.html +0 -187
  26. package/src/invisible-image-explicit.html +0 -146
  27. package/src/invisible-image-implicit.html +0 -187
  28. package/src/invisible-pow-explicit.html +0 -146
  29. package/src/invisible-pow-implicit.html +0 -94
  30. package/src/invisible-puzzle-explicit.html +0 -145
  31. package/src/invisible-puzzle-implicit.html +0 -94
  32. package/src/plugins/code-snippet-injector.ts +0 -179
  33. package/src/plugins/form-filler-injector.ts +0 -148
  34. package/src/plugins/layout-injector.ts +0 -256
  35. package/src/plugins/logo.ts +0 -15
  36. package/src/plugins/pages.ts +0 -219
  37. package/src/plugins/placement-injector.ts +0 -114
  38. package/src/plugins/slots.ts +0 -32
  39. package/src/plugins/status-log-injector.ts +0 -143
  40. package/src/pow-explicit-web3.html +0 -179
  41. package/src/pow-explicit.html +0 -143
  42. package/src/pow-implicit-sessionid.html +0 -209
  43. package/src/pow-implicit.html +0 -192
  44. package/src/puzzle-bind-explicit.html +0 -83
  45. package/src/puzzle-explicit.html +0 -151
  46. package/src/puzzle-implicit.html +0 -192
  47. package/src/styles/demo.css +0 -803
  48. package/src/tests/explicitRender.unit.test.ts +0 -49
  49. package/src/tests/plugins.unit.test.ts +0 -490
  50. package/tsconfig.cjs.json +0 -25
  51. package/tsconfig.json +0 -31
  52. package/tsconfig.tsbuildinfo +0 -1
  53. package/tsconfig.types.json +0 -9
@@ -1,143 +0,0 @@
1
- // Copyright 2021-2026 Prosopo (UK) Ltd.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- // Vite plugin that adds the event log. Demo pages report what the widget is
16
- // doing through window.updateCaptchaStatus.
17
- import type { IndexHtmlTransformContext, Plugin } from "vite";
18
- import { fillSlot } from "./slots.js";
19
-
20
- // Opening tag of <head>, attributes and all.
21
- const HEAD_OPEN = /<head(\s[^>]*)?>/i;
22
-
23
- export default function statusLogInjector(): Plugin {
24
- // A classic script at the very start of <head>, so it runs during parsing,
25
- // before any module script. By the time this plugin runs ("post"), Vite has
26
- // already hoisted the page's own entry module into <head>, and module
27
- // scripts run in document order: defined in the module below, the helper
28
- // did not exist yet when the explicit-render pages called it at top level,
29
- // so they threw before render() and never showed a widget.
30
- const updateStatusJs = `
31
- <script>
32
- function updateCaptchaStatus(message, type = 'info') {
33
- const statusContainer = document.getElementById('captcha-status');
34
- if (!statusContainer) return;
35
-
36
- const time = document.createElement('span');
37
- time.className = 'status-item__time';
38
- time.textContent = new Date().toLocaleTimeString();
39
- const dot = document.createElement('span');
40
- dot.className = 'status-item__dot';
41
- const text = document.createElement('span');
42
- text.className = 'status-item__message';
43
- text.textContent = message;
44
-
45
- const statusItem = document.createElement('div');
46
- statusItem.className = \`status-item status-\${type}\`;
47
- statusItem.append(time, dot, text);
48
- statusContainer.appendChild(statusItem);
49
- statusContainer.scrollTop = statusContainer.scrollHeight;
50
-
51
- console.log(\`CAPTCHA Status: \${message}\`);
52
- }
53
-
54
- window.updateCaptchaStatus = updateCaptchaStatus;
55
- </script>
56
- `;
57
-
58
- // A module, after the page's entry module, because it wraps the callbacks
59
- // that module defines.
60
- const statusLogJs = `
61
- <script type="module">
62
- const updateCaptchaStatus = window.updateCaptchaStatus;
63
-
64
- // Wrap the page's own callbacks so every page logs the same events.
65
- const originalOnCaptchaFailed = window.onCaptchaFailed;
66
- window.onCaptchaFailed = function() {
67
- updateCaptchaStatus('Challenge failed - CAPTCHA verification could not be completed', 'error');
68
- if (originalOnCaptchaFailed) originalOnCaptchaFailed();
69
- };
70
-
71
- const originalOnCaptchaVerified = window.onCaptchaVerified;
72
- window.onCaptchaVerified = function(output) {
73
- updateCaptchaStatus('Challenge passed successfully!', 'success');
74
- updateCaptchaStatus(\`Token generated: \${output.substring(0, 15)}...\`, 'success');
75
- if (originalOnCaptchaVerified) originalOnCaptchaVerified(output);
76
- };
77
-
78
- const originalOnActionHandler = window.onActionHandler;
79
- window.onActionHandler = function(token) {
80
- const procaptchaElements = document.getElementsByName('procaptcha-response');
81
-
82
- if (!procaptchaElements.length) {
83
- updateCaptchaStatus('Error: No CAPTCHA response token found', 'error');
84
- alert("Must complete captcha");
85
- return;
86
- }
87
-
88
- updateCaptchaStatus('Form submission initiated with valid CAPTCHA token', 'info');
89
- if (originalOnActionHandler) originalOnActionHandler(token);
90
- };
91
-
92
- document.addEventListener('procaptcha:execute', function(e) {
93
- const url = window.location.pathname;
94
- const isFrictionless = url.includes('frictionless');
95
- const isImage = url.includes('image');
96
- const isPow = url.includes('pow');
97
-
98
- let captchaType = 'unknown';
99
- if (isFrictionless) captchaType = 'frictionless';
100
- else if (isImage) captchaType = 'image';
101
- else if (isPow) captchaType = 'pow';
102
-
103
- updateCaptchaStatus(\`CAPTCHA execution started: type=\${captchaType}\`, 'info');
104
- updateCaptchaStatus(\`Container: \${e.detail.containerId}, timestamp: \${new Date(e.detail.timestamp).toLocaleTimeString()}\`, 'info');
105
- });
106
- </script>
107
- `;
108
-
109
- const statusLogHtml = `<div id="captcha-status" class="captcha-status" aria-live="polite"></div>`;
110
-
111
- return {
112
- name: "status-log-injector",
113
- transformIndexHtml: {
114
- order: "post",
115
- handler(html: string, _ctx: IndexHtmlTransformContext): string {
116
- if (!html.includes("<body") || !html.includes("</body>")) {
117
- return html;
118
- }
119
-
120
- if (html.includes('id="captcha-status"')) {
121
- return html;
122
- }
123
-
124
- const withHelper = HEAD_OPEN.test(html)
125
- ? html.replace(HEAD_OPEN, (open) => `${open}${updateStatusJs}`)
126
- : html;
127
- const withJs = withHelper.replace(
128
- "</head>",
129
- () => `${statusLogJs}</head>`,
130
- );
131
-
132
- const inSlot = fillSlot(withJs, "events", statusLogHtml);
133
- if (inSlot) {
134
- return inSlot;
135
- }
136
- if (withJs.includes("</form>")) {
137
- return withJs.replace("</form>", () => `</form>${statusLogHtml}`);
138
- }
139
- return withJs.replace("</body>", () => `${statusLogHtml}</body>`);
140
- },
141
- },
142
- };
143
- }
@@ -1,179 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
-
5
- <title>Procaptcha demo: Proof of Work, explicit rendering, web3</title>
6
- <script type="module">
7
-
8
- document.addEventListener('DOMContentLoaded', function() {
9
- updateCaptchaStatus('Page loaded - Initializing CAPTCHA system', 'info');
10
-
11
- // Monitor DOM for CAPTCHA initialization
12
- const observer = new MutationObserver((mutations) => {
13
- mutations.forEach((mutation) => {
14
- if (mutation.addedNodes.length) {
15
- for (let i = 0; i < mutation.addedNodes.length; i++) {
16
- const node = mutation.addedNodes[i];
17
- if (node.classList && (node.classList.contains('procaptcha') ||
18
- node.querySelector && node.querySelector('.procaptcha'))) {
19
- updateCaptchaStatus('CAPTCHA DOM elements initialized', 'info');
20
- observer.disconnect();
21
- break;
22
- }
23
- }
24
- }
25
- });
26
- });
27
-
28
- observer.observe(document.body, { childList: true, subtree: true });
29
- });
30
-
31
- </script>
32
- </head>
33
- <body>
34
- <div class="demo-card">
35
-
36
- <form id="demo-form" class="demo-form">
37
- <h2>Create an account</h2>
38
-
39
- <div class="demo-field">
40
- <label for="name">Name</label>
41
- <input type="text" id="name" name="name" required />
42
- </div>
43
-
44
- <div class="demo-field">
45
- <label for="email">Email</label>
46
- <input type="email" id="email" name="email" required />
47
- </div>
48
-
49
- <div id="procaptcha-container"></div>
50
-
51
- <button type="submit" class="demo-button">Submit</button>
52
-
53
- <div id="error"></div>
54
- </form>
55
-
56
- <div id="result" class="demo-result" style="display: none;"></div>
57
-
58
- </div>
59
-
60
- <script type="module">
61
- import { render } from "%VITE_BUNDLE_URL%"
62
- import { web3AccountsSubscribe, web3Enable } from "@polkadot/extension-dapp";
63
-
64
- // Form validation function
65
- function validateForm() {
66
- const nameInput = document.getElementById('name');
67
- const emailInput = document.getElementById('email');
68
- const errorDisplay = document.getElementById('error');
69
-
70
- if (!nameInput.value || !emailInput.value) {
71
- errorDisplay.textContent = 'Please fill out all fields';
72
- errorDisplay.style.display = 'block';
73
- window.updateCaptchaStatus('Form validation failed: Empty fields', 'error');
74
- return false;
75
- }
76
-
77
- // Basic email validation
78
- const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
79
- if (!emailPattern.test(emailInput.value)) {
80
- errorDisplay.textContent = 'Please enter a valid email address';
81
- errorDisplay.style.display = 'block';
82
- window.updateCaptchaStatus('Form validation failed: Invalid email format', 'error');
83
- return false;
84
- }
85
-
86
- errorDisplay.style.display = 'none';
87
- window.updateCaptchaStatus('Form validation passed', 'info');
88
- return true;
89
- }
90
-
91
- // Callback for successful CAPTCHA verification
92
- function handleCaptchaResponse(token) {
93
- console.log('Procaptcha verified, token:', token);
94
- window.updateCaptchaStatus('Challenge passed successfully!', 'success');
95
- window.updateCaptchaStatus(`Token generated: ${token.substring(0, 15)}...`, 'success');
96
-
97
- const name = document.getElementById('name').value;
98
- const email = document.getElementById('email').value;
99
-
100
- // Display result
101
- const resultElement = document.getElementById('result');
102
- resultElement.innerHTML = `<strong>Form submitted with:</strong><br>
103
- - Name: ${name}<br>
104
- - Email: ${email}<br>
105
- - Procaptcha verified: Yes`;
106
- resultElement.style.display = 'block';
107
-
108
- window.updateCaptchaStatus('Form submission completed', 'success');
109
- }
110
-
111
- // Callback for failed CAPTCHA verification
112
- function handleCaptchaFailed() {
113
- console.log('Captcha verification failed');
114
- window.updateCaptchaStatus('Challenge failed - CAPTCHA verification could not be completed', 'error');
115
- document.getElementById('error').textContent = 'CAPTCHA verification failed. Please try again.';
116
- document.getElementById('error').style.display = 'block';
117
- }
118
-
119
- // Get web3 accounts and create select element
120
- async function getWeb3Accounts() {
121
- return new Promise((resolve) =>{ web3AccountsSubscribe((accounts) => {
122
- if (accounts.length === 0) {
123
- window.updateCaptchaStatus('No accounts found. Please connect your wallet.', 'error');
124
- } else {
125
- window.updateCaptchaStatus(`Connected to ${accounts.length} account(s).`, 'info');
126
- // render a modal and get the user to select 1 account
127
- const accountSelect = document.createElement('select');
128
- accountSelect.id = 'account-select';
129
- accountSelect.classList.add('account-select');
130
- accounts.forEach((account) => {
131
- const option = document.createElement('option');
132
- option.value = account.address;
133
- option.textContent = `${account.meta.name} (${account.address})`;
134
- accountSelect.appendChild(option);
135
- });
136
- const accountContainer = document.createElement('div');
137
- accountContainer.innerHTML = '<label for="account-select"><h2>Select Account:</h2></label>';
138
- accountContainer.appendChild(accountSelect);
139
- document.getElementById('demo-form').prepend(accountContainer);
140
- window.updateCaptchaStatus('Accounts loaded successfully', 'info');
141
- }
142
- resolve(accounts);
143
- })});
144
- }
145
-
146
- // Wait for DOM content to be loaded
147
- document.addEventListener('DOMContentLoaded', async function() {
148
- window.updateCaptchaStatus('Initializing CAPTCHA with explicit render call', 'info');
149
-
150
- await web3Enable("Procaptcha Demo");
151
-
152
- await getWeb3Accounts();
153
-
154
- // Render the CAPTCHA
155
- const account = document.getElementById('account-select') ? document.getElementById('account-select').value : null;
156
- window.updateCaptchaStatus(`Rendering the CAPTCHA for account ${account}`, 'info');
157
- const widgetId = await render(document.getElementById('procaptcha-container'), {
158
- siteKey: import.meta.env.PROSOPO_SITE_KEY_POW,
159
- callback: handleCaptchaResponse,
160
- "failed-callback": handleCaptchaFailed,
161
- web3:true,
162
- userAccountAddress: account
163
- });
164
-
165
- window.updateCaptchaStatus('CAPTCHA render function called with widget ID: ' + widgetId, 'info');
166
-
167
- // Add form submit handler
168
- document.getElementById('demo-form').addEventListener('submit', function(e) {
169
- e.preventDefault();
170
- window.updateCaptchaStatus('Form submission attempted', 'info');
171
- if (validateForm()) {
172
- // Form is valid, CAPTCHA verification will be handled by the callback
173
- window.updateCaptchaStatus('Waiting for CAPTCHA verification', 'info');
174
- }
175
- });
176
- });
177
- </script>
178
- </body>
179
- </html>
@@ -1,143 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
-
5
- <title>Procaptcha demo: Proof of Work, explicit rendering</title>
6
- <script type="module">
7
-
8
- document.addEventListener('DOMContentLoaded', function() {
9
- updateCaptchaStatus('Page loaded - Initializing CAPTCHA system', 'info');
10
-
11
- // Monitor DOM for CAPTCHA initialization
12
- const observer = new MutationObserver((mutations) => {
13
- mutations.forEach((mutation) => {
14
- if (mutation.addedNodes.length) {
15
- for (let i = 0; i < mutation.addedNodes.length; i++) {
16
- const node = mutation.addedNodes[i];
17
- if (node.classList && (node.classList.contains('procaptcha') ||
18
- node.querySelector && node.querySelector('.procaptcha'))) {
19
- updateCaptchaStatus('CAPTCHA DOM elements initialized', 'info');
20
- observer.disconnect();
21
- break;
22
- }
23
- }
24
- }
25
- });
26
- });
27
-
28
- observer.observe(document.body, { childList: true, subtree: true });
29
- });
30
-
31
- </script>
32
- </head>
33
- <body>
34
- <div class="demo-card">
35
-
36
- <form id="demo-form" class="demo-form">
37
- <h2>Create an account</h2>
38
-
39
- <div class="demo-field">
40
- <label for="name">Name</label>
41
- <input type="text" id="name" name="name" required />
42
- </div>
43
-
44
- <div class="demo-field">
45
- <label for="email">Email</label>
46
- <input type="email" id="email" name="email" required />
47
- </div>
48
-
49
- <div id="procaptcha-container"></div>
50
-
51
- <button type="submit" class="demo-button">Submit</button>
52
-
53
- <div id="error"></div>
54
- </form>
55
-
56
- <div id="result" class="demo-result" style="display: none;"></div>
57
-
58
- </div>
59
-
60
- <script type="module">
61
- import { render } from "%VITE_BUNDLE_URL%"
62
-
63
- // Form validation function
64
- function validateForm() {
65
- const nameInput = document.getElementById('name');
66
- const emailInput = document.getElementById('email');
67
- const errorDisplay = document.getElementById('error');
68
-
69
- if (!nameInput.value || !emailInput.value) {
70
- errorDisplay.textContent = 'Please fill out all fields';
71
- errorDisplay.style.display = 'block';
72
- window.updateCaptchaStatus('Form validation failed: Empty fields', 'error');
73
- return false;
74
- }
75
-
76
- // Basic email validation
77
- const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
78
- if (!emailPattern.test(emailInput.value)) {
79
- errorDisplay.textContent = 'Please enter a valid email address';
80
- errorDisplay.style.display = 'block';
81
- window.updateCaptchaStatus('Form validation failed: Invalid email format', 'error');
82
- return false;
83
- }
84
-
85
- errorDisplay.style.display = 'none';
86
- window.updateCaptchaStatus('Form validation passed', 'info');
87
- return true;
88
- }
89
-
90
- // Callback for successful CAPTCHA verification
91
- function handleCaptchaResponse(token) {
92
- console.log('Procaptcha verified, token:', token);
93
- window.updateCaptchaStatus('Challenge passed successfully!', 'success');
94
- window.updateCaptchaStatus(`Token generated: ${token.substring(0, 15)}...`, 'success');
95
-
96
- const name = document.getElementById('name').value;
97
- const email = document.getElementById('email').value;
98
-
99
- // Display result
100
- const resultElement = document.getElementById('result');
101
- resultElement.innerHTML = `<strong>Form submitted with:</strong><br>
102
- - Name: ${name}<br>
103
- - Email: ${email}<br>
104
- - Procaptcha verified: Yes`;
105
- resultElement.style.display = 'block';
106
-
107
- window.updateCaptchaStatus('Form submission completed', 'success');
108
- }
109
-
110
- // Callback for failed CAPTCHA verification
111
- function handleCaptchaFailed() {
112
- console.log('Captcha verification failed');
113
- window.updateCaptchaStatus('Challenge failed - CAPTCHA verification could not be completed', 'error');
114
- document.getElementById('error').textContent = 'CAPTCHA verification failed. Please try again.';
115
- document.getElementById('error').style.display = 'block';
116
- }
117
-
118
- // Wait for DOM content to be loaded
119
- document.addEventListener('DOMContentLoaded', async function() {
120
- window.updateCaptchaStatus('Initializing CAPTCHA with explicit render call', 'info');
121
-
122
- // Render the CAPTCHA
123
- const widgetId = await render(document.getElementById('procaptcha-container'), {
124
- siteKey: import.meta.env.PROSOPO_SITE_KEY_POW,
125
- callback: handleCaptchaResponse,
126
- "failed-callback": handleCaptchaFailed
127
- });
128
-
129
- window.updateCaptchaStatus('CAPTCHA render function called with widget ID: ' + widgetId, 'info');
130
-
131
- // Add form submit handler
132
- document.getElementById('demo-form').addEventListener('submit', function(e) {
133
- e.preventDefault();
134
- window.updateCaptchaStatus('Form submission attempted', 'info');
135
- if (validateForm()) {
136
- // Form is valid, CAPTCHA verification will be handled by the callback
137
- window.updateCaptchaStatus('Waiting for CAPTCHA verification', 'info');
138
- }
139
- });
140
- });
141
- </script>
142
- </body>
143
- </html>
@@ -1,209 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
-
5
- <title>Procaptcha demo: Proof of Work, client session id</title>
6
- <script type="module">
7
-
8
- // The site's own per-user session id. Rendered onto the widget via
9
- // data-sessionid and sent again at verify as clientSessionId; the
10
- // provider only accepts the token when the two agree.
11
- //
12
- // `?mismatch=1` deliberately verifies with a DIFFERENT id, which must
13
- // be rejected — that is the half of the contract that proves the
14
- // correlation is actually enforced rather than silently skipped.
15
- const CLIENT_SESSION_ID = 'cypress-session-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
16
- const MISMATCHED_SESSION_ID = 'cypress-session-99999999-9999-9999-9999-999999999999';
17
- const verifyingSessionId = () =>
18
- new URLSearchParams(window.location.search).get('mismatch') === '1'
19
- ? MISMATCHED_SESSION_ID
20
- : CLIENT_SESSION_ID;
21
-
22
- window.addEventListener('load', () => {
23
-
24
- window.setIsError = (isError) => {
25
- const messageContainer = document.getElementById('messageContainer');
26
- messageContainer.style.color = isError ? 'red' : 'black';
27
- messageContainer.style.display = 'block';
28
- };
29
-
30
- window.setMessage = (message) => {
31
- document.getElementById('message').innerText = message;
32
- };
33
-
34
- window.onLoggedIn = (token) => {
35
- updateCaptchaStatus('Logged in, fetching private resource', 'info');
36
- const url = new URL("/private", config.serverUrl).href;
37
- console.log("getting private resource with token ", token, "at", url);
38
- fetch(url, {
39
- method: "GET",
40
- headers: {
41
- Origin: "http://localhost:9232", // TODO: change this to env var
42
- "Content-Type": "application/json",
43
- Authorization: `Bearer ${token}`,
44
- },
45
- })
46
- .then(async (res) => {
47
- try {
48
- const jsonRes = await res.json();
49
- if (res.status === 200) {
50
- updateCaptchaStatus(`Successfully accessed private resource`, 'success');
51
- setMessage(jsonRes.message);
52
- } else {
53
- updateCaptchaStatus(`Failed to access private resource: ${res.status}`, 'error');
54
- }
55
- } catch (err) {
56
- console.log(err);
57
- updateCaptchaStatus(`Error parsing response: ${err}`, 'error');
58
- }
59
- })
60
- .catch((err) => {
61
- console.log(err);
62
- updateCaptchaStatus(`Fetch error: ${err}`, 'error');
63
- });
64
- };
65
-
66
- window.onActionHandler = () => {
67
- updateCaptchaStatus('Form submission initiated', 'info');
68
-
69
- const procaptchaElements = document.getElementsByName('procaptcha-response');
70
-
71
- if (!procaptchaElements.length) {
72
- updateCaptchaStatus('Error: No CAPTCHA response found', 'error');
73
- alert("Must complete captcha");
74
- return
75
- }
76
-
77
- const procaptchaToken = procaptchaElements[0].value;
78
- updateCaptchaStatus(`Token received: ${procaptchaToken.substring(0, 15)}...`, 'success');
79
-
80
- const payload = {
81
- email: document.getElementById('email').value,
82
- name: document.getElementById('name').value,
83
- password: document.getElementById('password').value,
84
- siteKey: import.meta.env.PROSOPO_SITE_KEY_POW,
85
- "procaptcha-response": procaptchaToken,
86
- clientSessionId: verifyingSessionId(),
87
- };
88
- const url = new URL('signup', import.meta.env.PROSOPO_SERVER_URL).href;
89
- console.log("posting to", url, "with payload", payload);
90
- fetch(url, {
91
- method: "POST",
92
- headers: {
93
- "Content-Type": "application/json",
94
- },
95
- body: JSON.stringify(payload),
96
- contentType: "application/json",
97
- }).then((response) => {
98
- return new Promise((resolve) => response.json()
99
- .then((json) => resolve({
100
- status: response.status,
101
- ok: response.ok,
102
- json,
103
- })))
104
- })
105
- .then(async ({status, json, ok}) => {
106
- console.log("status", status, "json", json.message, "ok", ok);
107
- console.log("json", json)
108
- try {
109
- if (status !== 200) {
110
- updateCaptchaStatus(`API Error: ${json.message}`, 'error');
111
- setIsError(true);
112
- setMessage(json.message);
113
- } else {
114
- updateCaptchaStatus(`API Success: ${json.message}`, 'success');
115
- setIsError(false);
116
- setMessage(json.message);
117
- }
118
- } catch (err) {
119
- console.log(err);
120
- updateCaptchaStatus(`Error processing response: ${err}`, 'error');
121
- }
122
- })
123
- .catch((err) => {
124
- console.log(err);
125
- updateCaptchaStatus(`Fetch error: ${err}`, 'error');
126
- setIsError(true);
127
- setMessage("Error: " + err);
128
- });
129
- };
130
-
131
- updateCaptchaStatus('Page loaded - Initializing CAPTCHA system', 'info');
132
-
133
- // Monitor DOM for CAPTCHA initialization
134
- const observer = new MutationObserver((mutations) => {
135
- mutations.forEach((mutation) => {
136
- if (mutation.addedNodes.length) {
137
- for (let i = 0; i < mutation.addedNodes.length; i++) {
138
- const node = mutation.addedNodes[i];
139
- if (node.classList && (node.classList.contains('procaptcha') ||
140
- node.querySelector && node.querySelector('.procaptcha'))) {
141
- updateCaptchaStatus('CAPTCHA DOM elements initialized', 'info');
142
- observer.disconnect();
143
- break;
144
- }
145
- }
146
- }
147
- });
148
- });
149
-
150
- observer.observe(document.body, { childList: true, subtree: true });
151
- });
152
-
153
- window.onCaptchaFailed = function () {
154
- console.log('Challenge failed');
155
- updateCaptchaStatus('Challenge failed - CAPTCHA verification could not be completed', 'error');
156
- }
157
-
158
- window.onCaptchaVerified = (output) => {
159
- console.log('Challenge passed');
160
- updateCaptchaStatus('Challenge passed successfully!', 'success');
161
- updateCaptchaStatus(`Token generated: ${output.substring(0, 15)}...`, 'success');
162
- }
163
-
164
- // Add custom event listener for CAPTCHA verification stages
165
- document.addEventListener('DOMContentLoaded', function() {
166
- setTimeout(() => {
167
- updateCaptchaStatus('CAPTCHA script loaded and initialized', 'info');
168
- updateCaptchaStatus('Waiting for user interaction...', 'info');
169
- }, 500);
170
- });
171
- </script>
172
- <script id="procaptchaScript" type="module" src="%VITE_BUNDLE_URL%" async defer></script>
173
- </head>
174
- <body>
175
-
176
- <div class="demo-card">
177
-
178
- <form action="%PROSOPO_SERVER_URL%/signup" method="POST" class="demo-form">
179
- <h2>Create an account</h2>
180
- <p class="demo-note">Renders with <code>data-sessionid</code> and verifies with the same <code>clientSessionId</code>.</p>
181
- <div class="demo-field">
182
- <label for="name">Name</label>
183
- <input id="name" type="text" name="name" required/>
184
- </div>
185
- <div class="demo-field">
186
- <label for="email">Email Address</label>
187
- <input id="email" type="email" name="email" required/>
188
- </div>
189
- <div class="demo-field">
190
- <label for="password">Password</label>
191
- <input id="password" type="password" name="password" required/>
192
- </div>
193
- <div class="demo-field">
194
- <div
195
- class="procaptcha"
196
- data-theme="light"
197
- data-sitekey="%PROSOPO_SITE_KEY_POW%"
198
- data-sessionid="cypress-session-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
199
- data-failed-callback="onCaptchaFailed"
200
- data-callback="onCaptchaVerified"
201
- ></div>
202
- </div>
203
- <div id="messageContainer" style="display: none; color: black;"><span id="message"></span></div>
204
- <button type="button" class="demo-button" onclick="onActionHandler()" data-cy="submit-button">Submit</button>
205
- </form>
206
-
207
- </div>
208
- </body>
209
- </html>