@prosopo/client-bundle-example 2.10.24 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$cjs.log +5 -4
- package/.turbo/turbo-build$colon$tsc.log +11 -11
- package/.turbo/turbo-build.log +6 -5
- package/CHANGELOG.md +16 -0
- package/dist/cjs/index.cjs +13 -41
- package/dist/cjs/plugins/pages.cjs +113 -0
- package/dist/index.js +2 -42
- package/dist/plugins/pages.js +103 -0
- package/package.json +2 -2
- package/src/frictionless-explicit-web3.html +10 -23
- package/src/frictionless-explicit.html +10 -22
- package/src/frictionless-implicit.html +60 -86
- package/src/frictionless-manual-start.html +13 -33
- package/src/image-explicit-web3.html +8 -24
- package/src/image-explicit.html +8 -23
- package/src/image-implicit.html +192 -0
- package/src/index.html +11 -26
- package/src/index.ts +1 -62
- package/src/invisible-frictionless-explicit.html +8 -17
- package/src/invisible-frictionless-implicit.html +8 -25
- package/src/invisible-image-explicit.html +8 -23
- package/src/invisible-image-implicit.html +8 -24
- package/src/invisible-pow-explicit.html +8 -23
- package/src/invisible-pow-implicit.html +9 -21
- package/src/invisible-puzzle-explicit.html +8 -23
- package/src/invisible-puzzle-implicit.html +9 -21
- package/src/plugins/code-snippet-injector.ts +179 -0
- package/src/plugins/form-filler-injector.ts +36 -121
- package/src/plugins/layout-injector.ts +238 -0
- package/src/plugins/logo.ts +15 -0
- package/src/plugins/pages.ts +219 -0
- package/src/plugins/placement-injector.ts +25 -64
- package/src/plugins/slots.ts +32 -0
- package/src/plugins/status-log-injector.ts +35 -114
- package/src/pow-explicit-web3.html +8 -24
- package/src/pow-explicit.html +8 -23
- package/src/pow-implicit-sessionid.html +10 -24
- package/src/pow-implicit.html +9 -24
- package/src/puzzle-bind-explicit.html +9 -24
- package/src/puzzle-explicit.html +8 -23
- package/src/puzzle-implicit.html +9 -24
- package/src/styles/demo.css +803 -0
- package/src/tests/plugins.unit.test.ts +285 -118
- package/tsconfig.tsbuildinfo +1 -1
- package/vite.config.ts +5 -5
- package/src/plugins/explanation-injector.ts +0 -294
- package/src/plugins/navigation-injector.ts +0 -606
- package/src/styles/captcha.css +0 -78
- package/src/styles/field.css +0 -12
- package/src/tests/floatLabel.unit.test.ts +0 -195
- package/src/tests/floatLabelReady.unit.test.ts +0 -36
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/client-bundle-example@2.
|
|
2
|
+
> @prosopo/client-bundle-example@2.11.0 build:cjs
|
|
3
3
|
> NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
|
|
4
4
|
|
|
5
5
|
ViteCommonJSConfig: .
|
|
@@ -27,9 +27,10 @@ ViteCommonJSConfig: .
|
|
|
27
27
|
[36mvite v8.1.5 [32mbuilding ssr environment for production...[36m[39m
|
|
28
28
|
Bundle build started
|
|
29
29
|
[2K
|
|
30
|
-
✓
|
|
30
|
+
✓ 3 modules transformed.
|
|
31
31
|
rendering chunks...
|
|
32
32
|
computing gzip size...
|
|
33
|
-
dist/cjs/index.cjs
|
|
33
|
+
dist/cjs/index.cjs 0.71 kB │ gzip: 0.27 kB
|
|
34
|
+
dist/cjs/plugins/pages.cjs 4.63 kB │ gzip: 1.20 kB
|
|
34
35
|
|
|
35
|
-
[32m✓ built in
|
|
36
|
+
[32m✓ built in 55ms[39m
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/client-bundle-example@2.
|
|
2
|
+
> @prosopo/client-bundle-example@2.11.0 build:tsc
|
|
3
3
|
> tsc --build --verbose
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
2:42:19 PM - Projects in this build:
|
|
6
6
|
* ../../dev/config/tsconfig.json
|
|
7
7
|
* ../../packages/util/tsconfig.json
|
|
8
8
|
* ../../packages/logger/tsconfig.json
|
|
@@ -12,21 +12,21 @@
|
|
|
12
12
|
* ../../packages/types/tsconfig.json
|
|
13
13
|
* tsconfig.json
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
2:42:19 PM - 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
16
|
|
|
17
|
-
|
|
17
|
+
2:42:19 PM - 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
18
|
|
|
19
|
-
|
|
19
|
+
2:42:19 PM - 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
20
|
|
|
21
|
-
|
|
21
|
+
2:42:19 PM - Project '../../packages/dotenv/tsconfig.json' is up to date because newest input '../../packages/dotenv/src/tests/env.unit.test.ts' is older than output '../../packages/dotenv/tsconfig.tsbuildinfo'
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
2:42:19 PM - 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
24
|
|
|
25
|
-
|
|
25
|
+
2:42:19 PM - 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
26
|
|
|
27
|
-
|
|
27
|
+
2:42:19 PM - Project '../../packages/types/tsconfig.json' is up to date because newest input '../../packages/types/src/types.test-d.ts' is older than output '../../packages/types/tsconfig.tsbuildinfo'
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
2:42:19 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
2:42:19 PM - Building project '/home/runner/work/captcha/captcha/demos/client-bundle-example/tsconfig.json'...
|
|
32
32
|
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/client-bundle-example@2.
|
|
2
|
+
> @prosopo/client-bundle-example@2.11.0 build
|
|
3
3
|
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @prosopo/client-bundle-example@2.
|
|
6
|
+
> @prosopo/client-bundle-example@2.11.0 build:cross-env
|
|
7
7
|
> vite build --config vite.esm.config.ts --mode production
|
|
8
8
|
|
|
9
9
|
ViteEsmConfig: .
|
|
@@ -31,10 +31,11 @@ ViteEsmConfig: .
|
|
|
31
31
|
[36mvite v8.1.5 [32mbuilding ssr environment for production...[36m[39m
|
|
32
32
|
Bundle build started
|
|
33
33
|
[2K
|
|
34
|
-
✓
|
|
34
|
+
✓ 3 modules transformed.
|
|
35
35
|
rendering chunks...
|
|
36
36
|
computing gzip size...
|
|
37
37
|
dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
|
|
38
|
-
dist/index.js
|
|
38
|
+
dist/index.js 0.42 kB │ gzip: 0.19 kB
|
|
39
|
+
dist/plugins/pages.js 4.04 kB │ gzip: 1.15 kB
|
|
39
40
|
|
|
40
|
-
[32m✓ built in
|
|
41
|
+
[32m✓ built in 151ms[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @prosopo/client-bundle-example
|
|
2
2
|
|
|
3
|
+
## 2.11.0
|
|
4
|
+
### Minor Changes
|
|
5
|
+
|
|
6
|
+
- 2256f94: Redesign the demo site as a Prosopo-branded playground. Every demo page now has the prosopo.io header, a sidebar to switch captcha type, mode, rendering and challenge placement, the event log and the code for the current setup side by side, and sign-up links. The home page is now the frictionless captcha instead of the image captcha, which moves to `/image-implicit.html`; the cypress configs that opened the home page for the image captcha now open that page. The MUI stylesheet and the float-label script are gone.
|
|
7
|
+
|
|
8
|
+
### Patch Changes
|
|
9
|
+
|
|
10
|
+
- 7291d30: Fix the demo pages' status log dropping the captcha token. Its `onActionHandler` wrapper took no arguments, so invisible implicit pages (image and frictionless) called the real handler without a token, showed "Must complete captcha" and never submitted the form.
|
|
11
|
+
- 2fc615d: Restore the `frictionless-implicit.html` demo page.
|
|
12
|
+
|
|
13
|
+
The playground redesign renamed it to `image-implicit.html` and switched it to
|
|
14
|
+
an image site key, which left nothing serving that path. Suites outside this
|
|
15
|
+
repo navigate to it directly and were being answered by the dev server's
|
|
16
|
+
fallback to the index page — which happens to render a frictionless widget, so
|
|
17
|
+
they passed by luck rather than because the page they asked for existed.
|
|
18
|
+
|
|
3
19
|
## 2.10.24
|
|
4
20
|
### Patch Changes
|
|
5
21
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,41 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
(
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const update = () => {
|
|
15
|
-
const hasValue = input.type === "checkbox" || input.type === "radio" ? input.checked : input.value && input.value.trim() !== "";
|
|
16
|
-
if (document.activeElement === input || hasValue) wrapper.classList.add("label-hidden");
|
|
17
|
-
else wrapper.classList.remove("label-hidden");
|
|
18
|
-
};
|
|
19
|
-
for (const evt of [
|
|
20
|
-
"focus",
|
|
21
|
-
"input",
|
|
22
|
-
"blur",
|
|
23
|
-
"change",
|
|
24
|
-
"keyup",
|
|
25
|
-
"paste"
|
|
26
|
-
]) input.addEventListener(evt, update, { passive: true });
|
|
27
|
-
update();
|
|
28
|
-
}
|
|
29
|
-
const maxChecks = 12;
|
|
30
|
-
let checks = 0;
|
|
31
|
-
const iv = setInterval(() => {
|
|
32
|
-
checks++;
|
|
33
|
-
for (const w of wrappers) {
|
|
34
|
-
const input = w.querySelector("input,textarea,select");
|
|
35
|
-
if (input) input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
36
|
-
}
|
|
37
|
-
if (checks >= maxChecks) clearInterval(iv);
|
|
38
|
-
}, 250);
|
|
39
|
-
});
|
|
40
|
-
})();
|
|
41
|
-
//#endregion
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_pages = require("./plugins/pages.cjs");
|
|
3
|
+
exports.captchaTypeOptions = require_pages.captchaTypeOptions;
|
|
4
|
+
exports.defaultSetup = require_pages.defaultSetup;
|
|
5
|
+
exports.demoPages = require_pages.demoPages;
|
|
6
|
+
exports.findPageByPath = require_pages.findPageByPath;
|
|
7
|
+
exports.labelOf = require_pages.labelOf;
|
|
8
|
+
exports.modeOptions = require_pages.modeOptions;
|
|
9
|
+
exports.pagePathFromFilename = require_pages.pagePathFromFilename;
|
|
10
|
+
exports.relativePrefix = require_pages.relativePrefix;
|
|
11
|
+
exports.renderingOptions = require_pages.renderingOptions;
|
|
12
|
+
exports.renderingsFor = require_pages.renderingsFor;
|
|
13
|
+
exports.resolvePage = require_pages.resolvePage;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
let _prosopo_types = require("@prosopo/types");
|
|
2
|
+
//#region src/plugins/pages.ts
|
|
3
|
+
var captchaTypeOptions = [
|
|
4
|
+
{
|
|
5
|
+
value: _prosopo_types.CaptchaType.frictionless,
|
|
6
|
+
label: "Frictionless",
|
|
7
|
+
description: "Humans pass without a challenge. Bots get one."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
value: _prosopo_types.CaptchaType.pow,
|
|
11
|
+
label: "Proof of Work",
|
|
12
|
+
description: "The browser does a quick computation."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
value: _prosopo_types.CaptchaType.puzzle,
|
|
16
|
+
label: "Puzzle",
|
|
17
|
+
description: "Drag a piece into place."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
value: _prosopo_types.CaptchaType.image,
|
|
21
|
+
label: "Image",
|
|
22
|
+
description: "Pick the images that match."
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
var modeOptions = [{
|
|
26
|
+
value: "standard",
|
|
27
|
+
label: "Standard"
|
|
28
|
+
}, {
|
|
29
|
+
value: "invisible",
|
|
30
|
+
label: "Invisible"
|
|
31
|
+
}];
|
|
32
|
+
var renderingOptions = [
|
|
33
|
+
{
|
|
34
|
+
value: "implicit",
|
|
35
|
+
label: "Implicit",
|
|
36
|
+
description: "Add a div with your site key and the script renders the widget."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
value: "explicit",
|
|
40
|
+
label: "Explicit",
|
|
41
|
+
description: "Your own code calls render() when it is ready."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
value: "manual",
|
|
45
|
+
label: "Manual start",
|
|
46
|
+
description: "The widget shows straight away, but checks only start when you say."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
value: "bound",
|
|
50
|
+
label: "Bound button",
|
|
51
|
+
description: "Your own submit button opens the challenge."
|
|
52
|
+
}
|
|
53
|
+
];
|
|
54
|
+
var page = (path, captchaType, mode, rendering) => ({
|
|
55
|
+
path,
|
|
56
|
+
captchaType,
|
|
57
|
+
mode,
|
|
58
|
+
rendering
|
|
59
|
+
});
|
|
60
|
+
var indexPage = page("index.html", _prosopo_types.CaptchaType.frictionless, "standard", "implicit");
|
|
61
|
+
var defaultSetup = indexPage;
|
|
62
|
+
var demoPages = [
|
|
63
|
+
indexPage,
|
|
64
|
+
page("frictionless-explicit.html", _prosopo_types.CaptchaType.frictionless, "standard", "explicit"),
|
|
65
|
+
page("frictionless-manual-start.html", _prosopo_types.CaptchaType.frictionless, "standard", "manual"),
|
|
66
|
+
page("invisible-frictionless-implicit.html", _prosopo_types.CaptchaType.frictionless, "invisible", "implicit"),
|
|
67
|
+
page("invisible-frictionless-explicit.html", _prosopo_types.CaptchaType.frictionless, "invisible", "explicit"),
|
|
68
|
+
page("pow-implicit.html", _prosopo_types.CaptchaType.pow, "standard", "implicit"),
|
|
69
|
+
page("pow-explicit.html", _prosopo_types.CaptchaType.pow, "standard", "explicit"),
|
|
70
|
+
page("invisible-pow-implicit.html", _prosopo_types.CaptchaType.pow, "invisible", "implicit"),
|
|
71
|
+
page("invisible-pow-explicit.html", _prosopo_types.CaptchaType.pow, "invisible", "explicit"),
|
|
72
|
+
page("puzzle-implicit.html", _prosopo_types.CaptchaType.puzzle, "standard", "implicit"),
|
|
73
|
+
page("puzzle-explicit.html", _prosopo_types.CaptchaType.puzzle, "standard", "explicit"),
|
|
74
|
+
page("puzzle-bind-explicit.html", _prosopo_types.CaptchaType.puzzle, "standard", "bound"),
|
|
75
|
+
page("invisible-puzzle-implicit.html", _prosopo_types.CaptchaType.puzzle, "invisible", "implicit"),
|
|
76
|
+
page("invisible-puzzle-explicit.html", _prosopo_types.CaptchaType.puzzle, "invisible", "explicit"),
|
|
77
|
+
page("image-implicit.html", _prosopo_types.CaptchaType.image, "standard", "implicit"),
|
|
78
|
+
page("image-explicit.html", _prosopo_types.CaptchaType.image, "standard", "explicit"),
|
|
79
|
+
page("invisible-image-implicit.html", _prosopo_types.CaptchaType.image, "invisible", "implicit"),
|
|
80
|
+
page("invisible-image-explicit.html", _prosopo_types.CaptchaType.image, "invisible", "explicit")
|
|
81
|
+
];
|
|
82
|
+
var isSetup = (candidate, setup) => candidate.captchaType === setup.captchaType && candidate.mode === setup.mode && candidate.rendering === setup.rendering;
|
|
83
|
+
var findPageByPath = (path) => demoPages.find((demoPage) => demoPage.path === path);
|
|
84
|
+
var resolvePage = (setup) => demoPages.find((demoPage) => isSetup(demoPage, setup)) ?? demoPages.find((demoPage) => isSetup(demoPage, {
|
|
85
|
+
...setup,
|
|
86
|
+
rendering: "implicit"
|
|
87
|
+
})) ?? demoPages.find((demoPage) => isSetup(demoPage, {
|
|
88
|
+
...setup,
|
|
89
|
+
mode: "standard",
|
|
90
|
+
rendering: "implicit"
|
|
91
|
+
})) ?? indexPage;
|
|
92
|
+
var renderingsFor = (captchaType, mode) => renderingOptions.filter(({ value }) => demoPages.some((demoPage) => isSetup(demoPage, {
|
|
93
|
+
captchaType,
|
|
94
|
+
mode,
|
|
95
|
+
rendering: value
|
|
96
|
+
})));
|
|
97
|
+
var labelOf = (options, value) => options.find((option) => option.value === value)?.label ?? String(value);
|
|
98
|
+
var pagePathFromFilename = (filename) => {
|
|
99
|
+
return (filename ?? "").replace(/\\/g, "/").match(/^(?:.*\/)?(?:src|dist)\/(.+)$/)?.[1] ?? "";
|
|
100
|
+
};
|
|
101
|
+
var relativePrefix = (pagePath) => "../".repeat((pagePath.match(/\//g) ?? []).length);
|
|
102
|
+
//#endregion
|
|
103
|
+
exports.captchaTypeOptions = captchaTypeOptions;
|
|
104
|
+
exports.defaultSetup = defaultSetup;
|
|
105
|
+
exports.demoPages = demoPages;
|
|
106
|
+
exports.findPageByPath = findPageByPath;
|
|
107
|
+
exports.labelOf = labelOf;
|
|
108
|
+
exports.modeOptions = modeOptions;
|
|
109
|
+
exports.pagePathFromFilename = pagePathFromFilename;
|
|
110
|
+
exports.relativePrefix = relativePrefix;
|
|
111
|
+
exports.renderingOptions = renderingOptions;
|
|
112
|
+
exports.renderingsFor = renderingsFor;
|
|
113
|
+
exports.resolvePage = resolvePage;
|
package/dist/index.js
CHANGED
|
@@ -1,43 +1,3 @@
|
|
|
1
1
|
import "./_virtual/_rolldown/runtime.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
function whenDOMReady(fn) {
|
|
5
|
-
if (document.readyState !== "loading") fn();
|
|
6
|
-
else document.addEventListener("DOMContentLoaded", fn);
|
|
7
|
-
}
|
|
8
|
-
whenDOMReady(() => {
|
|
9
|
-
const wrappers = Array.from(document.querySelectorAll(".mui-textfield--float-label"));
|
|
10
|
-
for (const wrapper of wrappers) {
|
|
11
|
-
const input = wrapper.querySelector("input, textarea, select");
|
|
12
|
-
const label = wrapper.querySelector("label");
|
|
13
|
-
if (!input || !label) return;
|
|
14
|
-
if (!input.getAttribute("aria-label") && label.textContent) input.setAttribute("aria-label", label.textContent.trim());
|
|
15
|
-
const update = () => {
|
|
16
|
-
const hasValue = input.type === "checkbox" || input.type === "radio" ? input.checked : input.value && input.value.trim() !== "";
|
|
17
|
-
if (document.activeElement === input || hasValue) wrapper.classList.add("label-hidden");
|
|
18
|
-
else wrapper.classList.remove("label-hidden");
|
|
19
|
-
};
|
|
20
|
-
for (const evt of [
|
|
21
|
-
"focus",
|
|
22
|
-
"input",
|
|
23
|
-
"blur",
|
|
24
|
-
"change",
|
|
25
|
-
"keyup",
|
|
26
|
-
"paste"
|
|
27
|
-
]) input.addEventListener(evt, update, { passive: true });
|
|
28
|
-
update();
|
|
29
|
-
}
|
|
30
|
-
const maxChecks = 12;
|
|
31
|
-
let checks = 0;
|
|
32
|
-
const iv = setInterval(() => {
|
|
33
|
-
checks++;
|
|
34
|
-
for (const w of wrappers) {
|
|
35
|
-
const input = w.querySelector("input,textarea,select");
|
|
36
|
-
if (input) input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
37
|
-
}
|
|
38
|
-
if (checks >= maxChecks) clearInterval(iv);
|
|
39
|
-
}, 250);
|
|
40
|
-
});
|
|
41
|
-
})();
|
|
42
|
-
//#endregion
|
|
43
|
-
export {};
|
|
2
|
+
import { captchaTypeOptions, defaultSetup, demoPages, findPageByPath, labelOf, modeOptions, pagePathFromFilename, relativePrefix, renderingOptions, renderingsFor, resolvePage } from "./plugins/pages.js";
|
|
3
|
+
export { captchaTypeOptions, defaultSetup, demoPages, findPageByPath, labelOf, modeOptions, pagePathFromFilename, relativePrefix, renderingOptions, renderingsFor, resolvePage };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { CaptchaType } from "@prosopo/types";
|
|
2
|
+
//#region src/plugins/pages.ts
|
|
3
|
+
var captchaTypeOptions = [
|
|
4
|
+
{
|
|
5
|
+
value: CaptchaType.frictionless,
|
|
6
|
+
label: "Frictionless",
|
|
7
|
+
description: "Humans pass without a challenge. Bots get one."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
value: CaptchaType.pow,
|
|
11
|
+
label: "Proof of Work",
|
|
12
|
+
description: "The browser does a quick computation."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
value: CaptchaType.puzzle,
|
|
16
|
+
label: "Puzzle",
|
|
17
|
+
description: "Drag a piece into place."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
value: CaptchaType.image,
|
|
21
|
+
label: "Image",
|
|
22
|
+
description: "Pick the images that match."
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
var modeOptions = [{
|
|
26
|
+
value: "standard",
|
|
27
|
+
label: "Standard"
|
|
28
|
+
}, {
|
|
29
|
+
value: "invisible",
|
|
30
|
+
label: "Invisible"
|
|
31
|
+
}];
|
|
32
|
+
var renderingOptions = [
|
|
33
|
+
{
|
|
34
|
+
value: "implicit",
|
|
35
|
+
label: "Implicit",
|
|
36
|
+
description: "Add a div with your site key and the script renders the widget."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
value: "explicit",
|
|
40
|
+
label: "Explicit",
|
|
41
|
+
description: "Your own code calls render() when it is ready."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
value: "manual",
|
|
45
|
+
label: "Manual start",
|
|
46
|
+
description: "The widget shows straight away, but checks only start when you say."
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
value: "bound",
|
|
50
|
+
label: "Bound button",
|
|
51
|
+
description: "Your own submit button opens the challenge."
|
|
52
|
+
}
|
|
53
|
+
];
|
|
54
|
+
var page = (path, captchaType, mode, rendering) => ({
|
|
55
|
+
path,
|
|
56
|
+
captchaType,
|
|
57
|
+
mode,
|
|
58
|
+
rendering
|
|
59
|
+
});
|
|
60
|
+
var indexPage = page("index.html", CaptchaType.frictionless, "standard", "implicit");
|
|
61
|
+
var defaultSetup = indexPage;
|
|
62
|
+
var demoPages = [
|
|
63
|
+
indexPage,
|
|
64
|
+
page("frictionless-explicit.html", CaptchaType.frictionless, "standard", "explicit"),
|
|
65
|
+
page("frictionless-manual-start.html", CaptchaType.frictionless, "standard", "manual"),
|
|
66
|
+
page("invisible-frictionless-implicit.html", CaptchaType.frictionless, "invisible", "implicit"),
|
|
67
|
+
page("invisible-frictionless-explicit.html", CaptchaType.frictionless, "invisible", "explicit"),
|
|
68
|
+
page("pow-implicit.html", CaptchaType.pow, "standard", "implicit"),
|
|
69
|
+
page("pow-explicit.html", CaptchaType.pow, "standard", "explicit"),
|
|
70
|
+
page("invisible-pow-implicit.html", CaptchaType.pow, "invisible", "implicit"),
|
|
71
|
+
page("invisible-pow-explicit.html", CaptchaType.pow, "invisible", "explicit"),
|
|
72
|
+
page("puzzle-implicit.html", CaptchaType.puzzle, "standard", "implicit"),
|
|
73
|
+
page("puzzle-explicit.html", CaptchaType.puzzle, "standard", "explicit"),
|
|
74
|
+
page("puzzle-bind-explicit.html", CaptchaType.puzzle, "standard", "bound"),
|
|
75
|
+
page("invisible-puzzle-implicit.html", CaptchaType.puzzle, "invisible", "implicit"),
|
|
76
|
+
page("invisible-puzzle-explicit.html", CaptchaType.puzzle, "invisible", "explicit"),
|
|
77
|
+
page("image-implicit.html", CaptchaType.image, "standard", "implicit"),
|
|
78
|
+
page("image-explicit.html", CaptchaType.image, "standard", "explicit"),
|
|
79
|
+
page("invisible-image-implicit.html", CaptchaType.image, "invisible", "implicit"),
|
|
80
|
+
page("invisible-image-explicit.html", CaptchaType.image, "invisible", "explicit")
|
|
81
|
+
];
|
|
82
|
+
var isSetup = (candidate, setup) => candidate.captchaType === setup.captchaType && candidate.mode === setup.mode && candidate.rendering === setup.rendering;
|
|
83
|
+
var findPageByPath = (path) => demoPages.find((demoPage) => demoPage.path === path);
|
|
84
|
+
var resolvePage = (setup) => demoPages.find((demoPage) => isSetup(demoPage, setup)) ?? demoPages.find((demoPage) => isSetup(demoPage, {
|
|
85
|
+
...setup,
|
|
86
|
+
rendering: "implicit"
|
|
87
|
+
})) ?? demoPages.find((demoPage) => isSetup(demoPage, {
|
|
88
|
+
...setup,
|
|
89
|
+
mode: "standard",
|
|
90
|
+
rendering: "implicit"
|
|
91
|
+
})) ?? indexPage;
|
|
92
|
+
var renderingsFor = (captchaType, mode) => renderingOptions.filter(({ value }) => demoPages.some((demoPage) => isSetup(demoPage, {
|
|
93
|
+
captchaType,
|
|
94
|
+
mode,
|
|
95
|
+
rendering: value
|
|
96
|
+
})));
|
|
97
|
+
var labelOf = (options, value) => options.find((option) => option.value === value)?.label ?? String(value);
|
|
98
|
+
var pagePathFromFilename = (filename) => {
|
|
99
|
+
return (filename ?? "").replace(/\\/g, "/").match(/^(?:.*\/)?(?:src|dist)\/(.+)$/)?.[1] ?? "";
|
|
100
|
+
};
|
|
101
|
+
var relativePrefix = (pagePath) => "../".repeat((pagePath.match(/\//g) ?? []).length);
|
|
102
|
+
//#endregion
|
|
103
|
+
export { captchaTypeOptions, defaultSetup, demoPages, findPageByPath, labelOf, modeOptions, pagePathFromFilename, relativePrefix, renderingOptions, renderingsFor, resolvePage };
|
package/package.json
CHANGED
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
"start": "NODE_ENV=${NODE_ENV:-development}; vite serve ./src --port 9232 --config vite.config.ts --mode=$NODE_ENV",
|
|
26
26
|
"test": "NODE_ENV=${NODE_ENV:-test}; npx vitest run --config ./vite.test.config.ts"
|
|
27
27
|
},
|
|
28
|
-
"version": "2.
|
|
28
|
+
"version": "2.11.0",
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@emotion/cache": "11.14.0",
|
|
31
31
|
"@prosopo/config": "3.3.17",
|
|
32
32
|
"@prosopo/dotenv": "3.0.56",
|
|
33
33
|
"@prosopo/locale": "3.4.3",
|
|
34
|
-
"@prosopo/types": "5.
|
|
34
|
+
"@prosopo/types": "5.9.0",
|
|
35
35
|
"@types/node": "22.5.5",
|
|
36
36
|
"@vitest/coverage-v8": "4.1.11",
|
|
37
37
|
"concurrently": "9.0.1",
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
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
4
|
|
|
7
|
-
<
|
|
8
|
-
<title>Procaptcha demo: Frictionless CAPTCHA</title>
|
|
9
|
-
<link href="styles/captcha.css" rel="stylesheet" type="text/css"/>
|
|
5
|
+
<title>Procaptcha demo: Frictionless, explicit rendering, web3</title>
|
|
10
6
|
<script type="module">
|
|
11
7
|
window.onCaptchaFailed = function () {
|
|
12
8
|
console.log('Challenge failed');
|
|
@@ -142,42 +138,34 @@
|
|
|
142
138
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
143
139
|
});
|
|
144
140
|
|
|
145
|
-
// updateCaptchaStatus is now provided by status-log-injector
|
|
146
141
|
</script>
|
|
147
142
|
</head>
|
|
148
143
|
<body>
|
|
149
144
|
|
|
150
|
-
<div class="
|
|
151
|
-
<h1>Frictionless CAPTCHA - Explicit Rendering</h1>
|
|
152
|
-
<p>This example demonstrates how to use Procaptcha in frictionless mode with explicit rendering.</p>
|
|
145
|
+
<div class="demo-card">
|
|
153
146
|
|
|
154
|
-
<!--
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
<
|
|
158
|
-
<div class="mui-textfield mui-textfield--float-label">
|
|
147
|
+
<!-- nosemgrep: python.django.security.django-no-csrf-token.django-no-csrf-token -->
|
|
148
|
+
<form action="%PROSOPO_SERVER_URL%/signup" method="POST" class="demo-form" id="demo-form">
|
|
149
|
+
<h2>Create an account</h2>
|
|
150
|
+
<div class="demo-field">
|
|
159
151
|
<label for="name">Name</label>
|
|
160
152
|
<input id="name" type="text" name="name" required/>
|
|
161
153
|
</div>
|
|
162
|
-
<div class="
|
|
154
|
+
<div class="demo-field">
|
|
163
155
|
<label for="email">Email Address</label>
|
|
164
156
|
<input id="email" type="email" name="email" required/>
|
|
165
157
|
</div>
|
|
166
|
-
<div class="
|
|
158
|
+
<div class="demo-field">
|
|
167
159
|
<label for="password">Password</label>
|
|
168
160
|
<input id="password" type="password" name="password" required/>
|
|
169
161
|
</div>
|
|
170
|
-
<div class="
|
|
162
|
+
<div class="demo-field">
|
|
171
163
|
<div id="procaptcha-container"></div>
|
|
172
164
|
</div>
|
|
173
165
|
<div id="messageContainer" style="display: none; color: black;"><span id="message"></span></div>
|
|
174
|
-
<button type="button" class="
|
|
166
|
+
<button type="button" class="demo-button" onclick="onActionHandler()" data-cy="submit-button">Submit</button>
|
|
175
167
|
</form>
|
|
176
168
|
|
|
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
169
|
</div>
|
|
182
170
|
<script type="module">
|
|
183
171
|
// Pattern to avoid race condition between Procaptcha script loading and Procaptcha render function call
|
|
@@ -201,7 +189,6 @@
|
|
|
201
189
|
// render a modal and get the user to select 1 account
|
|
202
190
|
const accountSelect = document.createElement('select');
|
|
203
191
|
accountSelect.id = 'account-select';
|
|
204
|
-
accountSelect.classList.add('mui-select');
|
|
205
192
|
accountSelect.classList.add('account-select');
|
|
206
193
|
accounts.forEach((account) => {
|
|
207
194
|
const option = document.createElement('option');
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
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
4
|
|
|
7
|
-
<
|
|
8
|
-
<title>Procaptcha demo: Frictionless CAPTCHA</title>
|
|
9
|
-
<link href="styles/captcha.css" rel="stylesheet" type="text/css"/>
|
|
5
|
+
<title>Procaptcha demo: Frictionless, explicit rendering</title>
|
|
10
6
|
<script type="module">
|
|
11
7
|
window.onCaptchaFailed = function () {
|
|
12
8
|
console.log('Challenge failed');
|
|
@@ -142,42 +138,34 @@
|
|
|
142
138
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
143
139
|
});
|
|
144
140
|
|
|
145
|
-
// updateCaptchaStatus is now provided by status-log-injector
|
|
146
141
|
</script>
|
|
147
142
|
</head>
|
|
148
143
|
<body>
|
|
149
144
|
|
|
150
|
-
<div class="
|
|
151
|
-
<h1>Frictionless CAPTCHA - Explicit Rendering</h1>
|
|
152
|
-
<p>This example demonstrates how to use Procaptcha in frictionless mode with explicit rendering.</p>
|
|
145
|
+
<div class="demo-card">
|
|
153
146
|
|
|
154
|
-
<!--
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
<
|
|
158
|
-
<div class="mui-textfield mui-textfield--float-label">
|
|
147
|
+
<!-- nosemgrep: python.django.security.django-no-csrf-token.django-no-csrf-token -->
|
|
148
|
+
<form action="%PROSOPO_SERVER_URL%/signup" method="POST" class="demo-form">
|
|
149
|
+
<h2>Create an account</h2>
|
|
150
|
+
<div class="demo-field">
|
|
159
151
|
<label for="name">Name</label>
|
|
160
152
|
<input id="name" type="text" name="name" required/>
|
|
161
153
|
</div>
|
|
162
|
-
<div class="
|
|
154
|
+
<div class="demo-field">
|
|
163
155
|
<label for="email">Email Address</label>
|
|
164
156
|
<input id="email" type="email" name="email" required/>
|
|
165
157
|
</div>
|
|
166
|
-
<div class="
|
|
158
|
+
<div class="demo-field">
|
|
167
159
|
<label for="password">Password</label>
|
|
168
160
|
<input id="password" type="password" name="password" required/>
|
|
169
161
|
</div>
|
|
170
|
-
<div class="
|
|
162
|
+
<div class="demo-field">
|
|
171
163
|
<div id="procaptcha-container"></div>
|
|
172
164
|
</div>
|
|
173
165
|
<div id="messageContainer" style="display: none; color: black;"><span id="message"></span></div>
|
|
174
|
-
<button type="button" class="
|
|
166
|
+
<button type="button" class="demo-button" onclick="onActionHandler()" data-cy="submit-button">Submit</button>
|
|
175
167
|
</form>
|
|
176
168
|
|
|
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
169
|
</div>
|
|
182
170
|
<script type="module">
|
|
183
171
|
// Pattern to avoid race condition between Procaptcha script loading and Procaptcha render function call
|