@prosopo/client-bundle-example 2.10.11 → 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 +32 -0
- package/.turbo/turbo-build.log +11 -7
- package/CHANGELOG.md +53 -0
- package/README.md +3 -1
- package/env.development +7 -0
- package/env.production +6 -0
- package/env.staging +2 -2
- package/package.json +12 -6
- 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 +2 -2
- package/vite.config.ts +38 -5
- package/vite.esm.config.ts +1 -1
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/client-bundle-example@2.10.
|
|
2
|
+
> @prosopo/client-bundle-example@2.10.18 build:cjs
|
|
3
3
|
> NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
|
|
4
4
|
|
|
5
5
|
ViteCommonJSConfig: .
|
|
6
6
|
{
|
|
7
7
|
tsConfigPaths: [
|
|
8
8
|
'/home/runner/work/captcha/captcha/packages/dotenv/tsconfig.json',
|
|
9
|
-
'/home/runner/work/captcha/captcha/packages/
|
|
9
|
+
'/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
|
|
10
|
+
'/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
|
|
10
11
|
'/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
|
|
11
12
|
'/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
|
|
12
|
-
'/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
|
|
13
13
|
'/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json'
|
|
14
14
|
]
|
|
15
15
|
}
|
|
16
16
|
{
|
|
17
17
|
externals: [
|
|
18
18
|
'@prosopo/dotenv',
|
|
19
|
-
'@prosopo/
|
|
19
|
+
'@prosopo/logger',
|
|
20
|
+
'@prosopo/util',
|
|
20
21
|
'@prosopo/locale',
|
|
21
22
|
'@prosopo/types',
|
|
22
|
-
'@prosopo/util',
|
|
23
23
|
'@prosopo/util-crypto'
|
|
24
24
|
]
|
|
25
25
|
}
|
|
@@ -30,4 +30,4 @@ Build end
|
|
|
30
30
|
[32m✓[39m 1 modules transformed.
|
|
31
31
|
rendering chunks...
|
|
32
32
|
[2mdist/cjs/[22m[36mindex.cjs [39m[1m[2m1.62 kB[22m[1m[22m
|
|
33
|
-
[32m✓ built in
|
|
33
|
+
[32m✓ built in 100ms[39m
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
> @prosopo/client-bundle-example@2.10.18 build:tsc
|
|
3
|
+
> tsc --build --verbose
|
|
4
|
+
|
|
5
|
+
8:14:27 AM - Projects in this build:
|
|
6
|
+
* ../../dev/config/tsconfig.json
|
|
7
|
+
* ../../packages/util/tsconfig.json
|
|
8
|
+
* ../../packages/logger/tsconfig.json
|
|
9
|
+
* ../../packages/dotenv/tsconfig.json
|
|
10
|
+
* ../../packages/locale/tsconfig.json
|
|
11
|
+
* ../../packages/util-crypto/tsconfig.json
|
|
12
|
+
* ../../packages/types/tsconfig.json
|
|
13
|
+
* tsconfig.json
|
|
14
|
+
|
|
15
|
+
8:14:27 AM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
|
|
16
|
+
|
|
17
|
+
8:14:27 AM - Project '../../packages/util/tsconfig.json' is up to date because newest input '../../packages/util/src/url.ts' is older than output '../../packages/util/tsconfig.tsbuildinfo'
|
|
18
|
+
|
|
19
|
+
8:14:28 AM - Project '../../packages/logger/tsconfig.json' is up to date because newest input '../../packages/logger/src/index.ts' is older than output '../../packages/logger/tsconfig.tsbuildinfo'
|
|
20
|
+
|
|
21
|
+
8:14:28 AM - Project '../../packages/dotenv/tsconfig.json' is up to date because newest input '../../packages/dotenv/src/env.ts' is older than output '../../packages/dotenv/tsconfig.tsbuildinfo'
|
|
22
|
+
|
|
23
|
+
8:14:28 AM - Project '../../packages/locale/tsconfig.json' is up to date because newest input '../../packages/locale/src/translationKey.ts' is older than output '../../packages/locale/tsconfig.tsbuildinfo'
|
|
24
|
+
|
|
25
|
+
8:14:28 AM - Project '../../packages/util-crypto/tsconfig.json' is up to date because newest input '../../packages/util-crypto/src/types.ts' is older than output '../../packages/util-crypto/tsconfig.tsbuildinfo'
|
|
26
|
+
|
|
27
|
+
8:14:28 AM - Project '../../packages/types/tsconfig.json' is up to date because newest input '../../packages/types/src/procaptcha/api.ts' is older than output '../../packages/types/tsconfig.tsbuildinfo'
|
|
28
|
+
|
|
29
|
+
8:14:28 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
|
|
30
|
+
|
|
31
|
+
8:14:28 AM - Building project '/home/runner/work/captcha/captcha/demos/client-bundle-example/tsconfig.json'...
|
|
32
|
+
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/client-bundle-example@2.10.
|
|
3
|
-
>
|
|
2
|
+
> @prosopo/client-bundle-example@2.10.18 build
|
|
3
|
+
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> @prosopo/client-bundle-example@2.10.18 build:cross-env
|
|
7
|
+
> vite build --config vite.esm.config.ts --mode production
|
|
4
8
|
|
|
5
9
|
ViteEsmConfig: .
|
|
6
10
|
{
|
|
7
11
|
tsConfigPaths: [
|
|
8
12
|
'/home/runner/work/captcha/captcha/packages/dotenv/tsconfig.json',
|
|
9
|
-
'/home/runner/work/captcha/captcha/packages/
|
|
13
|
+
'/home/runner/work/captcha/captcha/packages/logger/tsconfig.json',
|
|
14
|
+
'/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
|
|
10
15
|
'/home/runner/work/captcha/captcha/packages/locale/tsconfig.json',
|
|
11
16
|
'/home/runner/work/captcha/captcha/packages/types/tsconfig.json',
|
|
12
|
-
'/home/runner/work/captcha/captcha/packages/util/tsconfig.json',
|
|
13
17
|
'/home/runner/work/captcha/captcha/packages/util-crypto/tsconfig.json'
|
|
14
18
|
]
|
|
15
19
|
}
|
|
16
20
|
{
|
|
17
21
|
externals: [
|
|
18
22
|
'@prosopo/dotenv',
|
|
19
|
-
'@prosopo/
|
|
23
|
+
'@prosopo/logger',
|
|
24
|
+
'@prosopo/util',
|
|
20
25
|
'@prosopo/locale',
|
|
21
26
|
'@prosopo/types',
|
|
22
|
-
'@prosopo/util',
|
|
23
27
|
'@prosopo/util-crypto'
|
|
24
28
|
]
|
|
25
29
|
}
|
|
@@ -30,4 +34,4 @@ Build end
|
|
|
30
34
|
[32m✓[39m 1 modules transformed.
|
|
31
35
|
rendering chunks...
|
|
32
36
|
[2mdist/[22m[36mindex.js [39m[1m[2m1.61 kB[22m[1m[22m
|
|
33
|
-
[32m✓ built in
|
|
37
|
+
[32m✓ built in 98ms[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @prosopo/client-bundle-example
|
|
2
2
|
|
|
3
|
+
## 2.10.18
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
- 5d87beb: chore(client-bundle-example): register invisible-puzzle explicit/implicit pages as Vite build entries so they are emitted in `dist` and reachable from the demo navigation.
|
|
7
|
+
|
|
8
|
+
## 2.10.17
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 273926d: Fix `/captcha/{type}` endpoints looping with "No session found" when the
|
|
12
|
+
Redis session cache and Mongo diverge: on a session lookup miss the cache
|
|
13
|
+
entry is now invalidated, so the next `/frictionless` falls through and
|
|
14
|
+
creates a fresh session instead of resurrecting the dead one.
|
|
15
|
+
|
|
16
|
+
Add invisible-mode support to the puzzle captcha widget: the
|
|
17
|
+
execute-event handler now drives the full phase transition
|
|
18
|
+
(`start` → `setChallengeData` → `dragging`), and the puzzle overlay is
|
|
19
|
+
rendered in invisible mode so the user can still solve the (inherently
|
|
20
|
+
interactive) drag challenge — only the checkbox UI is hidden.
|
|
21
|
+
|
|
22
|
+
Add `invisible-puzzle-implicit.html` / `invisible-puzzle-explicit.html`
|
|
23
|
+
demo pages, and surface both standard and invisible puzzle entries in
|
|
24
|
+
the client-bundle-example navbar.
|
|
25
|
+
- 5335647: Remove the obsolete `captchaType` render option from the client-bundle-example
|
|
26
|
+
demos; captcha type is now server-driven per site key, so the prop was a no-op.
|
|
27
|
+
|
|
28
|
+
## 2.10.16
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- dbcd098: Fix bug with chrome on ios
|
|
32
|
+
|
|
33
|
+
## 2.10.15
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- f5c8725: Fix bug with chrome on ios
|
|
37
|
+
|
|
38
|
+
## 2.10.14
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- 676c5f2: Use HTTPS in developmentwq
|
|
42
|
+
- c1d738f: Update env for tests
|
|
43
|
+
|
|
44
|
+
## 2.10.13
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- 8148587: Clustering
|
|
48
|
+
|
|
49
|
+
## 2.10.12
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- 0a38892: feat/cross-os-testing
|
|
53
|
+
- a8faa9a: bump license year
|
|
54
|
+
- 3acc333: Release 3.3.0
|
|
55
|
+
|
|
3
56
|
## 2.10.11
|
|
4
57
|
### Patch Changes
|
|
5
58
|
|
package/README.md
CHANGED
|
@@ -9,6 +9,8 @@ This project is a _minimal_ example demonstrating how to include the Prosopo Pro
|
|
|
9
9
|
Run these commands from the root of the [captcha](https://github.com/prosopo/captcha) repo:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
+
./setup-certs.sh && \
|
|
13
|
+
./install_cert.sh && \
|
|
12
14
|
cp dev/scripts/env.development dev/scripts/.env.development && \
|
|
13
15
|
cp dev/scripts/env.development packages/procaptcha-bundle/.env.development && \
|
|
14
16
|
docker compose --file ./docker/docker-compose.development.yml up -d && \
|
|
@@ -22,5 +24,5 @@ NODE_ENV=development npm run start:all
|
|
|
22
24
|
|
|
23
25
|
### 2. Visit the App
|
|
24
26
|
|
|
25
|
-
The app is now running in development mode. Open [
|
|
27
|
+
The app is now running in development mode. Open [https://localhost:9232](http://localhost:9232) to view it in the
|
|
26
28
|
browser.
|
package/env.development
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
PROSOPO_SITE_KEY=5DszzmqThZQCcPoJGZdyeL82FQWfrPAAbXLq1o3t6hTo2xAf
|
|
2
|
+
PROSOPO_SITE_KEY_FRICTIONLESS=5GCP69mhanZqJqnTvaaGvJCJZWSahz6xE2c7bTGETqSB5KDK
|
|
3
|
+
PROSOPO_SITE_KEY_POW=5Esjpa4ogV3CnkueyiXet7LL5z5mhvEyi5XJnDGbD2kjzD8W
|
|
4
|
+
PROSOPO_SITE_KEY_IMAGE=5DszzmqThZQCcPoJGZdyeL82FQWfrPAAbXLq1o3t6hTo2xAf
|
|
5
|
+
PROSOPO_SITE_KEY_PUZZLE=5CQ3QeyY82R8h8VWFKTic3FMB3WsbSJExZgbaUqfVJtAFPnb
|
|
6
|
+
PROSOPO_SERVER_URL=https://localhost:9228
|
|
7
|
+
VITE_BUNDLE_URL=https://localhost:9269/procaptcha.bundle.js
|
package/env.production
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
PROSOPO_SITE_KEY=5E7QGuzYgLJMH6qXQiCw62AUuLxPXRs1E6jitV4w8zTjDcKr
|
|
2
|
+
PROSOPO_SITE_KEY_FRICTIONLESS=5CcNvLUdiXFpzKDMjThGLSK9rhWHA1H4EF3zrgkpkjAdqmuP
|
|
3
|
+
PROSOPO_SITE_KEY_POW=5EoDBDkJscwosTHhHgGf4hqoU5s3WLwAjh8yTCQh72YYjVEt
|
|
4
|
+
PROSOPO_SITE_KEY_IMAGE=5E7QGuzYgLJMH6qXQiCw62AUuLxPXRs1E6jitV4w8zTjDcKr
|
|
5
|
+
PROSOPO_SERVER_URL=https://localhost:9228
|
|
6
|
+
VITE_BUNDLE_URL=https://js.prosopo.io/js/procaptcha.bundle.js
|
package/env.staging
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
PROSOPO_SITE_KEY=5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw
|
|
2
|
-
PROSOPO_SERVER_URL=
|
|
3
|
-
VITE_BUNDLE_URL=
|
|
2
|
+
PROSOPO_SERVER_URL=https://localhost:9228
|
|
3
|
+
VITE_BUNDLE_URL=https://staging-js.prosopo.io/js/procaptcha.bundle.js
|
|
4
4
|
PROSOPO_SITE_KEY_POW=5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw
|
|
5
5
|
PROSOPO_SITE_KEY_IMAGE=5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw
|
|
6
6
|
PROSOPO_SITE_KEY_FRICTIONLESS=5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw
|
package/package.json
CHANGED
|
@@ -16,20 +16,21 @@
|
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
18
|
"clean": "del-cli --verbose dist tsconfig.tsbuildinfo",
|
|
19
|
-
"build": "
|
|
19
|
+
"build": "npm run build:cross-env -- --mode ${NODE_ENV:-development}",
|
|
20
|
+
"build:cross-env": "vite build --config vite.esm.config.ts",
|
|
20
21
|
"build:tsc": "tsc --build --verbose",
|
|
21
22
|
"build:cjs": "NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV",
|
|
22
23
|
"bundle": "NODE_ENV=${NODE_ENV:-development}; vite build --config vite.config.ts --mode $NODE_ENV",
|
|
23
24
|
"typecheck": "tsc --project tsconfig.types.json",
|
|
24
25
|
"start": "NODE_ENV=${NODE_ENV:-development}; vite serve ./src --port 9232 --config vite.config.ts --mode=$NODE_ENV"
|
|
25
26
|
},
|
|
26
|
-
"version": "2.10.
|
|
27
|
+
"version": "2.10.18",
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"@emotion/cache": "11.11.0",
|
|
29
|
-
"@prosopo/config": "3.1
|
|
30
|
-
"@prosopo/dotenv": "3.0.
|
|
31
|
-
"@prosopo/locale": "3.
|
|
32
|
-
"@prosopo/types": "3.
|
|
30
|
+
"@prosopo/config": "3.3.1",
|
|
31
|
+
"@prosopo/dotenv": "3.0.43",
|
|
32
|
+
"@prosopo/locale": "3.2.4",
|
|
33
|
+
"@prosopo/types": "4.3.0",
|
|
33
34
|
"@types/node": "22.5.5",
|
|
34
35
|
"@vitest/coverage-v8": "3.2.4",
|
|
35
36
|
"concurrently": "9.0.1",
|
|
@@ -42,5 +43,10 @@
|
|
|
42
43
|
"typescript": "5.6.2",
|
|
43
44
|
"vite": "6.4.1",
|
|
44
45
|
"vitest": "3.2.4"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/prosopo/captcha.git",
|
|
50
|
+
"directory": "demos/client-bundle-example"
|
|
45
51
|
}
|
|
46
52
|
}
|
|
File without changes
|
|
@@ -0,0 +1,249 @@
|
|
|
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 demo: Frictionless CAPTCHA</title>
|
|
9
|
+
<link href="styles/captcha.css" rel="stylesheet" type="text/css"/>
|
|
10
|
+
<script type="module">
|
|
11
|
+
window.onCaptchaFailed = function () {
|
|
12
|
+
console.log('Challenge failed');
|
|
13
|
+
updateCaptchaStatus('Challenge failed - CAPTCHA verification could not be completed', 'error');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
window.addEventListener('load', () => {
|
|
17
|
+
updateCaptchaStatus('Page loaded - Initializing CAPTCHA system', 'info');
|
|
18
|
+
|
|
19
|
+
window.setIsError = (isError) => {
|
|
20
|
+
const messageContainer = document.getElementById('messageContainer');
|
|
21
|
+
messageContainer.style.color = isError ? 'red' : 'black';
|
|
22
|
+
messageContainer.style.display = 'block';
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
window.setMessage = (message) => {
|
|
26
|
+
document.getElementById('message').innerText = message;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
window.onLoggedIn = (token) => {
|
|
30
|
+
updateCaptchaStatus('Logged in, fetching private resource', 'info');
|
|
31
|
+
const url = new URL("/private", config.serverUrl).href;
|
|
32
|
+
console.log("getting private resource with token ", token, "at", url);
|
|
33
|
+
fetch(url, {
|
|
34
|
+
method: "GET",
|
|
35
|
+
headers: {
|
|
36
|
+
Origin: "http://localhost:9232", // TODO: change this to env var
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
Authorization: `Bearer ${token}`,
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
.then(async (res) => {
|
|
42
|
+
try {
|
|
43
|
+
const jsonRes = await res.json();
|
|
44
|
+
if (res.status === 200) {
|
|
45
|
+
updateCaptchaStatus(`Successfully accessed private resource`, 'success');
|
|
46
|
+
setMessage(jsonRes.message);
|
|
47
|
+
} else {
|
|
48
|
+
updateCaptchaStatus(`Failed to access private resource: ${res.status}`, 'error');
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
console.log(err);
|
|
52
|
+
updateCaptchaStatus(`Error parsing response: ${err}`, 'error');
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
.catch((err) => {
|
|
56
|
+
console.log(err);
|
|
57
|
+
updateCaptchaStatus(`Fetch error: ${err}`, 'error');
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
window.onActionHandler = () => {
|
|
62
|
+
updateCaptchaStatus('Form submission initiated', 'info');
|
|
63
|
+
|
|
64
|
+
const procaptchaElements = document.getElementsByName('procaptcha-response');
|
|
65
|
+
|
|
66
|
+
if (!procaptchaElements.length) {
|
|
67
|
+
updateCaptchaStatus('Error: No CAPTCHA response found', 'error');
|
|
68
|
+
alert("Must complete captcha");
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const procaptchaToken = procaptchaElements[0].value;
|
|
73
|
+
updateCaptchaStatus(`Token received: ${procaptchaToken.substring(0, 15)}...`, 'success');
|
|
74
|
+
|
|
75
|
+
const payload = {
|
|
76
|
+
email: document.getElementById('email').value,
|
|
77
|
+
name: document.getElementById('name').value,
|
|
78
|
+
password: document.getElementById('password').value,
|
|
79
|
+
siteKey: import.meta.env.PROSOPO_SITE_KEY_FRICTIONLESS,
|
|
80
|
+
"procaptcha-response": procaptchaToken,
|
|
81
|
+
};
|
|
82
|
+
const url = new URL('signup', import.meta.env.PROSOPO_SERVER_URL).href;
|
|
83
|
+
console.log("posting to", url, "with payload", payload);
|
|
84
|
+
fetch(url, {
|
|
85
|
+
method: "POST",
|
|
86
|
+
headers: {
|
|
87
|
+
"Content-Type": "application/json",
|
|
88
|
+
},
|
|
89
|
+
body: JSON.stringify(payload),
|
|
90
|
+
contentType: "application/json",
|
|
91
|
+
}).then((response) => {
|
|
92
|
+
return new Promise((resolve) => response.json()
|
|
93
|
+
.then((json) => resolve({
|
|
94
|
+
status: response.status,
|
|
95
|
+
ok: response.ok,
|
|
96
|
+
json,
|
|
97
|
+
})))
|
|
98
|
+
})
|
|
99
|
+
.then(async ({status, json, ok}) => {
|
|
100
|
+
console.log("status", status, "json", json.message, "ok", ok);
|
|
101
|
+
console.log("json", json)
|
|
102
|
+
try {
|
|
103
|
+
if (status !== 200) {
|
|
104
|
+
updateCaptchaStatus(`API Error: ${json.message}`, 'error');
|
|
105
|
+
setIsError(true);
|
|
106
|
+
setMessage(json.message);
|
|
107
|
+
} else {
|
|
108
|
+
updateCaptchaStatus(`API Success: ${json.message}`, 'success');
|
|
109
|
+
setIsError(false);
|
|
110
|
+
setMessage(json.message);
|
|
111
|
+
}
|
|
112
|
+
} catch (err) {
|
|
113
|
+
console.log(err);
|
|
114
|
+
updateCaptchaStatus(`Error processing response: ${err}`, 'error');
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
.catch((err) => {
|
|
118
|
+
console.log(err);
|
|
119
|
+
updateCaptchaStatus(`Fetch error: ${err}`, 'error');
|
|
120
|
+
setIsError(true);
|
|
121
|
+
setMessage("Error: " + err);
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// Monitor DOM for CAPTCHA initialization
|
|
126
|
+
const observer = new MutationObserver((mutations) => {
|
|
127
|
+
mutations.forEach((mutation) => {
|
|
128
|
+
if (mutation.addedNodes.length) {
|
|
129
|
+
for (let i = 0; i < mutation.addedNodes.length; i++) {
|
|
130
|
+
const node = mutation.addedNodes[i];
|
|
131
|
+
if (node.classList && (node.classList.contains('procaptcha') ||
|
|
132
|
+
node.querySelector && node.querySelector('.procaptcha'))) {
|
|
133
|
+
updateCaptchaStatus('CAPTCHA DOM elements initialized', 'info');
|
|
134
|
+
observer.disconnect();
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// updateCaptchaStatus is now provided by status-log-injector
|
|
146
|
+
</script>
|
|
147
|
+
</head>
|
|
148
|
+
<body>
|
|
149
|
+
|
|
150
|
+
<div class="mui-container">
|
|
151
|
+
<h1>Frictionless CAPTCHA - Explicit Rendering</h1>
|
|
152
|
+
<p>This example demonstrates how to use Procaptcha in frictionless mode with explicit rendering.</p>
|
|
153
|
+
|
|
154
|
+
<!-- CAPTCHA Status Display will be injected by the status-log-injector plugin -->
|
|
155
|
+
|
|
156
|
+
<form action="%PROSOPO_SERVER_URL%/signup" method="POST" class="mui-form" id="demo-form">
|
|
157
|
+
<h2>Example Login Form</h2>
|
|
158
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
159
|
+
<label for="name">Name</label>
|
|
160
|
+
<input id="name" type="text" name="name" required/>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
163
|
+
<label for="email">Email Address</label>
|
|
164
|
+
<input id="email" type="email" name="email" required/>
|
|
165
|
+
</div>
|
|
166
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
167
|
+
<label for="password">Password</label>
|
|
168
|
+
<input id="password" type="password" name="password" required/>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="mui-textfield mui-textfield--float-label">
|
|
171
|
+
<div id="procaptcha-container"></div>
|
|
172
|
+
</div>
|
|
173
|
+
<div id="messageContainer" style="display: none; color: black;"><span id="message"></span></div>
|
|
174
|
+
<button type="button" class="mui-btn mui-btn--raised" onclick="onActionHandler()" data-cy="submit-button">Submit</button>
|
|
175
|
+
</form>
|
|
176
|
+
|
|
177
|
+
<!-- Console output display area -->
|
|
178
|
+
<div id="console-output" class="console-output" style="display: none;"></div>
|
|
179
|
+
|
|
180
|
+
<!-- Explanation will be injected by the explanation-injector plugin -->
|
|
181
|
+
</div>
|
|
182
|
+
<script type="module">
|
|
183
|
+
// Pattern to avoid race condition between Procaptcha script loading and Procaptcha render function call
|
|
184
|
+
import { render } from "%VITE_BUNDLE_URL%"
|
|
185
|
+
import { web3AccountsSubscribe, web3Enable } from "@polkadot/extension-dapp";
|
|
186
|
+
|
|
187
|
+
// Define a callback function to be called when the CAPTCHA is verified
|
|
188
|
+
function onCaptchaVerified(output) {
|
|
189
|
+
console.log('Challenge passed');
|
|
190
|
+
window.updateCaptchaStatus('Challenge passed successfully!', 'success');
|
|
191
|
+
window.updateCaptchaStatus(`Token generated: ${output.substring(0, 15)}...`, 'success');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Get web3 accounts and create select element
|
|
195
|
+
async function getWeb3Accounts() {
|
|
196
|
+
return new Promise((resolve) =>{ web3AccountsSubscribe((accounts) => {
|
|
197
|
+
if (accounts.length === 0) {
|
|
198
|
+
window.updateCaptchaStatus('No accounts found. Please connect your wallet.', 'error');
|
|
199
|
+
} else {
|
|
200
|
+
window.updateCaptchaStatus(`Connected to ${accounts.length} account(s).`, 'info');
|
|
201
|
+
// render a modal and get the user to select 1 account
|
|
202
|
+
const accountSelect = document.createElement('select');
|
|
203
|
+
accountSelect.id = 'account-select';
|
|
204
|
+
accountSelect.classList.add('mui-select');
|
|
205
|
+
accountSelect.classList.add('account-select');
|
|
206
|
+
accounts.forEach((account) => {
|
|
207
|
+
const option = document.createElement('option');
|
|
208
|
+
option.value = account.address;
|
|
209
|
+
option.textContent = `${account.meta.name} (${account.address})`;
|
|
210
|
+
accountSelect.appendChild(option);
|
|
211
|
+
});
|
|
212
|
+
const accountContainer = document.createElement('div');
|
|
213
|
+
accountContainer.innerHTML = '<label for="account-select"><h2>Select Account:</h2></label>';
|
|
214
|
+
accountContainer.appendChild(accountSelect);
|
|
215
|
+
document.getElementById('demo-form').prepend(accountContainer);
|
|
216
|
+
window.updateCaptchaStatus('Accounts loaded successfully', 'info');
|
|
217
|
+
}
|
|
218
|
+
resolve(accounts);
|
|
219
|
+
})});
|
|
220
|
+
}
|
|
221
|
+
// Wait for DOM content to be loaded
|
|
222
|
+
document.addEventListener('DOMContentLoaded', async function() {
|
|
223
|
+
await web3Enable("Procaptcha Demo");
|
|
224
|
+
|
|
225
|
+
await getWeb3Accounts();
|
|
226
|
+
|
|
227
|
+
// Get the selected account from the dropdown
|
|
228
|
+
const account = document.getElementById('account-select') ? document.getElementById('account-select').value : null;
|
|
229
|
+
window.updateCaptchaStatus(`Rendering the CAPTCHA for account ${account}`, 'info');
|
|
230
|
+
|
|
231
|
+
// Get the Element using elementId
|
|
232
|
+
const captchaContainer = document.getElementById('procaptcha-container');
|
|
233
|
+
|
|
234
|
+
// Render the CAPTCHA
|
|
235
|
+
const widgetId = render(captchaContainer, {
|
|
236
|
+
siteKey: import.meta.env.PROSOPO_SITE_KEY_FRICTIONLESS,
|
|
237
|
+
callback: onCaptchaVerified,
|
|
238
|
+
"failed-callback": function () {
|
|
239
|
+
console.log('Challenge failed');
|
|
240
|
+
window.updateCaptchaStatus('Challenge failed - CAPTCHA verification could not be completed', 'error');
|
|
241
|
+
},
|
|
242
|
+
web3: true,
|
|
243
|
+
userAccountAddress: account
|
|
244
|
+
});
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
</script>
|
|
248
|
+
</body>
|
|
249
|
+
</html>
|