@prosopo/procaptcha-react 2.11.3 → 2.13.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 +15 -15
- package/.turbo/turbo-build$colon$tsc.log +22 -22
- package/.turbo/turbo-build.log +16 -15
- package/CHANGELOG.md +79 -0
- package/dist/cjs/components/button.cjs +98 -0
- package/dist/cjs/components/captchaComponent.cjs +225 -0
- package/dist/cjs/components/captchaWidget.cjs +210 -0
- package/dist/cjs/components/collector.cjs +49 -0
- package/dist/cjs/components/index.cjs +15 -6
- package/dist/cjs/components/modal.cjs +39 -0
- package/dist/cjs/components/procaptcha.cjs +23 -0
- package/dist/cjs/components/procaptchaWidget.cjs +166 -0
- package/dist/cjs/index.cjs +15 -6
- package/dist/cjs/util/index.cjs +6 -4
- package/dist/components/button.d.ts +9 -0
- package/dist/components/button.d.ts.map +1 -0
- package/dist/components/button.js +98 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/{CaptchaComponent.d.ts → captchaComponent.d.ts} +5 -3
- package/dist/components/captchaComponent.d.ts.map +1 -0
- package/dist/components/captchaComponent.js +225 -0
- package/dist/components/captchaComponent.js.map +1 -0
- package/dist/components/{CaptchaWidget.d.ts → captchaWidget.d.ts} +3 -2
- package/dist/components/captchaWidget.d.ts.map +1 -0
- package/dist/components/captchaWidget.js +210 -0
- package/dist/components/captchaWidget.js.map +1 -0
- package/dist/components/collector.d.ts +5 -4
- package/dist/components/collector.d.ts.map +1 -1
- package/dist/components/collector.js +46 -24
- package/dist/components/collector.js.map +1 -1
- package/dist/components/index.d.ts +7 -5
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +8 -4
- package/dist/components/index.js.map +1 -1
- package/dist/components/modal.d.ts +14 -0
- package/dist/components/modal.d.ts.map +1 -0
- package/dist/components/modal.js +39 -0
- package/dist/components/modal.js.map +1 -0
- package/dist/components/procaptcha.d.ts +7 -0
- package/dist/components/procaptcha.d.ts.map +1 -0
- package/dist/components/procaptcha.js +22 -0
- package/dist/components/procaptcha.js.map +1 -0
- package/dist/components/procaptchaWidget.d.ts +7 -0
- package/dist/components/procaptchaWidget.d.ts.map +1 -0
- package/dist/components/procaptchaWidget.js +166 -0
- package/dist/components/procaptchaWidget.js.map +1 -0
- package/dist/index.js +8 -4
- package/dist/tests/button.unit.test.d.ts.map +1 -1
- package/dist/tests/button.unit.test.js +99 -50
- package/dist/tests/button.unit.test.js.map +1 -1
- package/dist/tests/captchaComponent.unit.test.d.ts.map +1 -1
- package/dist/tests/captchaComponent.unit.test.js +35 -13
- package/dist/tests/captchaComponent.unit.test.js.map +1 -1
- package/dist/tests/captchaWidget.unit.test.d.ts.map +1 -1
- package/dist/tests/captchaWidget.unit.test.js +125 -12
- package/dist/tests/captchaWidget.unit.test.js.map +1 -1
- package/dist/tests/collector.unit.test.d.ts.map +1 -1
- package/dist/tests/collector.unit.test.js +43 -10
- package/dist/tests/collector.unit.test.js.map +1 -1
- package/dist/tests/harness.d.ts +2 -0
- package/dist/tests/harness.d.ts.map +1 -1
- package/dist/tests/harness.js +7 -0
- package/dist/tests/harness.js.map +1 -1
- package/dist/tests/modal.unit.test.d.ts.map +1 -1
- package/dist/tests/modal.unit.test.js +45 -16
- package/dist/tests/modal.unit.test.js.map +1 -1
- package/dist/tests/procaptcha.unit.test.d.ts.map +1 -1
- package/dist/tests/procaptcha.unit.test.js +37 -15
- package/dist/tests/procaptcha.unit.test.js.map +1 -1
- package/dist/tests/procaptchaReact.test-d.js +8 -6
- package/dist/tests/procaptchaReact.test-d.js.map +1 -1
- package/dist/tests/procaptchaWidget.unit.test.d.ts.map +1 -1
- package/dist/tests/procaptchaWidget.unit.test.js +121 -96
- package/dist/tests/procaptchaWidget.unit.test.js.map +1 -1
- package/dist/tests/render.d.ts +6 -7
- package/dist/tests/render.d.ts.map +1 -1
- package/dist/tests/render.js +23 -30
- package/dist/tests/render.js.map +1 -1
- package/dist/util/index.d.ts +8 -7
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +6 -4
- package/dist/util/index.js.map +1 -1
- package/package.json +9 -14
- package/vite.test.config.ts +1 -2
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +0 -23
- package/dist/cjs/components/Button.cjs +0 -81
- package/dist/cjs/components/CaptchaComponent.cjs +0 -171
- package/dist/cjs/components/CaptchaWidget.cjs +0 -129
- package/dist/cjs/components/Modal.cjs +0 -35
- package/dist/cjs/components/Procaptcha.cjs +0 -7
- package/dist/cjs/components/ProcaptchaWidget.cjs +0 -168
- package/dist/components/Button.d.ts +0 -11
- package/dist/components/Button.d.ts.map +0 -1
- package/dist/components/Button.js +0 -81
- package/dist/components/Button.js.map +0 -1
- package/dist/components/CaptchaComponent.d.ts.map +0 -1
- package/dist/components/CaptchaComponent.js +0 -171
- package/dist/components/CaptchaComponent.js.map +0 -1
- package/dist/components/CaptchaWidget.d.ts.map +0 -1
- package/dist/components/CaptchaWidget.js +0 -129
- package/dist/components/CaptchaWidget.js.map +0 -1
- package/dist/components/Modal.d.ts +0 -13
- package/dist/components/Modal.d.ts.map +0 -1
- package/dist/components/Modal.js +0 -33
- package/dist/components/Modal.js.map +0 -1
- package/dist/components/Procaptcha.d.ts +0 -4
- package/dist/components/Procaptcha.d.ts.map +0 -1
- package/dist/components/Procaptcha.js +0 -7
- package/dist/components/Procaptcha.js.map +0 -1
- package/dist/components/ProcaptchaWidget.d.ts +0 -4
- package/dist/components/ProcaptchaWidget.d.ts.map +0 -1
- package/dist/components/ProcaptchaWidget.js +0 -168
- package/dist/components/ProcaptchaWidget.js.map +0 -1
- package/dist/tests/setup.d.ts +0 -5
- package/dist/tests/setup.d.ts.map +0 -1
- package/dist/tests/setup.js +0 -3
- package/dist/tests/setup.js.map +0 -1
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
|
|
2
|
+
let _prosopo_widget_skeleton = require("@prosopo/widget-skeleton");
|
|
3
|
+
let _prosopo_common = require("@prosopo/common");
|
|
4
|
+
//#region src/components/captchaWidget.ts
|
|
5
|
+
var getHash = (item) => {
|
|
6
|
+
if (!item.hash) throw new _prosopo_common.ProsopoDatasetError("CAPTCHA.MISSING_ITEM_HASH", { context: { item } });
|
|
7
|
+
return item.hash;
|
|
8
|
+
};
|
|
9
|
+
var cellStyle = (gap) => ({
|
|
10
|
+
flexGrow: 1,
|
|
11
|
+
flexBasis: (0, _prosopo_procaptcha_common.threeColumnBasis)(gap),
|
|
12
|
+
boxSizing: "border-box"
|
|
13
|
+
});
|
|
14
|
+
var MIN_GRID_GAP = 8;
|
|
15
|
+
var MAX_GRID_GAP = 15;
|
|
16
|
+
var GRID_PADDING_JITTER = 4;
|
|
17
|
+
var MIN_WRAPPER_DEPTH = 0;
|
|
18
|
+
var MAX_WRAPPER_DEPTH = 2;
|
|
19
|
+
var CHECK_ICON_PATH = "M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z";
|
|
20
|
+
var themeOf = (themeColor) => "light" === themeColor ? _prosopo_widget_skeleton.lightTheme : _prosopo_widget_skeleton.darkTheme;
|
|
21
|
+
/** Drawn once per mounted grid, so tile centres move between page loads. */
|
|
22
|
+
var generateMetrics = (theme) => ({
|
|
23
|
+
gap: (0, _prosopo_widget_skeleton.randomInt)(MIN_GRID_GAP, MAX_GRID_GAP),
|
|
24
|
+
paddingTop: Math.max(0, theme.spacing.unit + (0, _prosopo_widget_skeleton.randomInt)(-GRID_PADDING_JITTER, GRID_PADDING_JITTER)),
|
|
25
|
+
paddingBottom: Math.max(0, theme.spacing.unit + (0, _prosopo_widget_skeleton.randomInt)(-GRID_PADDING_JITTER, GRID_PADDING_JITTER))
|
|
26
|
+
});
|
|
27
|
+
var gridStyle = (metrics) => ({
|
|
28
|
+
width: "100%",
|
|
29
|
+
height: "100%",
|
|
30
|
+
display: "flex",
|
|
31
|
+
flexDirection: "row",
|
|
32
|
+
flexWrap: "wrap",
|
|
33
|
+
justifyContent: "space-between",
|
|
34
|
+
paddingTop: `${metrics.paddingTop}px`,
|
|
35
|
+
paddingBottom: `${metrics.paddingBottom}px`,
|
|
36
|
+
gap: `${metrics.gap}px`
|
|
37
|
+
});
|
|
38
|
+
var selectionStyle = (theme, selected) => ({
|
|
39
|
+
borderRadius: selected ? theme.shape.tileSelected : theme.shape.tile,
|
|
40
|
+
transform: selected ? "scale(0.9)" : "none"
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* The selectable image grid.
|
|
44
|
+
*
|
|
45
|
+
* Tiles are rebuilt only when the round's `Captcha` changes identity. Every
|
|
46
|
+
* other update just flips overlay visibility — re-creating `<img>` elements on
|
|
47
|
+
* each selection would restart the image loads and flash the grid, which is the
|
|
48
|
+
* one place the old React reconciler was earning its keep.
|
|
49
|
+
*/
|
|
50
|
+
var mountCaptchaWidget = (container, initialProps) => {
|
|
51
|
+
let teardown = new _prosopo_procaptcha_common.Teardown();
|
|
52
|
+
let props = initialProps;
|
|
53
|
+
let renderedChallenge;
|
|
54
|
+
let tiles = [];
|
|
55
|
+
let focusedHash = null;
|
|
56
|
+
const metrics = generateMetrics(themeOf(initialProps.themeColor));
|
|
57
|
+
const grid = (0, _prosopo_procaptcha_common.createElement)("div", { style: gridStyle(metrics) });
|
|
58
|
+
const buildTile = (item, index) => {
|
|
59
|
+
const hash = getHash(item);
|
|
60
|
+
const theme = themeOf(props.themeColor);
|
|
61
|
+
const image = (0, _prosopo_procaptcha_common.createElement)("img", {
|
|
62
|
+
style: {
|
|
63
|
+
width: "100%",
|
|
64
|
+
display: "block",
|
|
65
|
+
objectFit: "cover",
|
|
66
|
+
aspectRatio: "1/1",
|
|
67
|
+
height: "auto",
|
|
68
|
+
overflow: "hidden",
|
|
69
|
+
borderStyle: "solid",
|
|
70
|
+
borderWidth: "1px",
|
|
71
|
+
borderColor: theme.palette.tile.border,
|
|
72
|
+
transition: "transform 200ms cubic-bezier(0.2, 0, 0, 1), border-radius 200ms"
|
|
73
|
+
},
|
|
74
|
+
attributes: {
|
|
75
|
+
src: item.data,
|
|
76
|
+
alt: `Captcha image ${index + 1}`
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
teardown.addEventListener(image, "error", () => {
|
|
80
|
+
const retryCount = Number(image.dataset.retryCount ?? "0") + 1;
|
|
81
|
+
image.dataset.retryCount = String(retryCount);
|
|
82
|
+
if (retryCount <= 3) image.src = `${item.data}?retry=${Date.now()}`;
|
|
83
|
+
});
|
|
84
|
+
const icon = (0, _prosopo_procaptcha_common.createSvgElement)("svg", {
|
|
85
|
+
style: {
|
|
86
|
+
backgroundColor: theme.palette.checkbox.fill,
|
|
87
|
+
display: "block",
|
|
88
|
+
width: "34px",
|
|
89
|
+
height: "34px",
|
|
90
|
+
padding: "7px",
|
|
91
|
+
borderRadius: "50%",
|
|
92
|
+
boxSizing: "border-box",
|
|
93
|
+
transition: "fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
|
|
94
|
+
userSelect: "none",
|
|
95
|
+
fill: theme.palette.checkbox.tick
|
|
96
|
+
},
|
|
97
|
+
attributes: {
|
|
98
|
+
focusable: "false",
|
|
99
|
+
"aria-hidden": "true",
|
|
100
|
+
viewBox: "0 0 24 24"
|
|
101
|
+
},
|
|
102
|
+
children: [(0, _prosopo_procaptcha_common.createSvgElement)("path", { attributes: { d: CHECK_ICON_PATH } })]
|
|
103
|
+
});
|
|
104
|
+
const overlay = (0, _prosopo_procaptcha_common.createElement)("div", {
|
|
105
|
+
style: {
|
|
106
|
+
position: "absolute",
|
|
107
|
+
top: 0,
|
|
108
|
+
left: 0,
|
|
109
|
+
bottom: 0,
|
|
110
|
+
right: 0,
|
|
111
|
+
height: "100%",
|
|
112
|
+
width: "100%",
|
|
113
|
+
display: "flex",
|
|
114
|
+
alignItems: "center",
|
|
115
|
+
justifyContent: "center",
|
|
116
|
+
backgroundColor: theme.palette.overlay,
|
|
117
|
+
borderRadius: theme.shape.tileSelected,
|
|
118
|
+
visibility: "hidden"
|
|
119
|
+
},
|
|
120
|
+
children: [icon]
|
|
121
|
+
});
|
|
122
|
+
const clickable = (0, _prosopo_procaptcha_common.createControl)(teardown, {
|
|
123
|
+
style: {
|
|
124
|
+
position: "relative",
|
|
125
|
+
cursor: "pointer",
|
|
126
|
+
height: "100%",
|
|
127
|
+
width: "100%",
|
|
128
|
+
padding: 0,
|
|
129
|
+
margin: 0,
|
|
130
|
+
border: "none",
|
|
131
|
+
background: "none",
|
|
132
|
+
appearance: "none",
|
|
133
|
+
display: "block"
|
|
134
|
+
},
|
|
135
|
+
children: [image, overlay],
|
|
136
|
+
onActivate: (event) => {
|
|
137
|
+
const fromPointer = "clientX" in event;
|
|
138
|
+
props.onClick(hash, fromPointer ? event.clientX : 0, fromPointer ? event.clientY : 0);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
teardown.addEventListener(clickable, "focus", () => {
|
|
142
|
+
focusedHash = clickable.matches(":focus-visible") ? hash : null;
|
|
143
|
+
applyFocusRing();
|
|
144
|
+
});
|
|
145
|
+
teardown.addEventListener(clickable, "blur", () => {
|
|
146
|
+
focusedHash = null;
|
|
147
|
+
applyFocusRing();
|
|
148
|
+
});
|
|
149
|
+
const cell = (0, _prosopo_procaptcha_common.createElement)("div", {
|
|
150
|
+
style: cellStyle(metrics.gap),
|
|
151
|
+
children: [clickable]
|
|
152
|
+
});
|
|
153
|
+
grid.appendChild((0, _prosopo_procaptcha_common.wrapRandomly)(cell, MIN_WRAPPER_DEPTH, MAX_WRAPPER_DEPTH));
|
|
154
|
+
return {
|
|
155
|
+
hash,
|
|
156
|
+
image,
|
|
157
|
+
overlay,
|
|
158
|
+
clickable
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
const applyFocusRing = () => {
|
|
162
|
+
const theme = themeOf(props.themeColor);
|
|
163
|
+
for (const tile of tiles) (0, _prosopo_procaptcha_common.applyStyles)(tile.clickable, focusedHash === tile.hash ? {
|
|
164
|
+
outline: `3px solid ${theme.palette.primary.main}`,
|
|
165
|
+
outlineOffset: "2px"
|
|
166
|
+
} : {
|
|
167
|
+
outline: "none",
|
|
168
|
+
outlineOffset: void 0
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
const rebuild = () => {
|
|
172
|
+
teardown.run();
|
|
173
|
+
teardown = new _prosopo_procaptcha_common.Teardown();
|
|
174
|
+
(0, _prosopo_procaptcha_common.clearElement)(grid);
|
|
175
|
+
(0, _prosopo_procaptcha_common.applyStyles)(grid, gridStyle(metrics));
|
|
176
|
+
tiles = props.challenge.items.map(buildTile);
|
|
177
|
+
renderedChallenge = props.challenge;
|
|
178
|
+
};
|
|
179
|
+
const applySelection = () => {
|
|
180
|
+
const theme = themeOf(props.themeColor);
|
|
181
|
+
for (const tile of tiles) {
|
|
182
|
+
const selected = props.solution.some((entry) => entry[0] === tile.hash);
|
|
183
|
+
(0, _prosopo_procaptcha_common.applyStyles)(tile.image, selectionStyle(theme, selected));
|
|
184
|
+
(0, _prosopo_procaptcha_common.applyStyles)(tile.overlay, { visibility: selected ? "visible" : "hidden" });
|
|
185
|
+
tile.clickable.setAttribute("aria-pressed", String(selected));
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
rebuild();
|
|
189
|
+
applySelection();
|
|
190
|
+
applyFocusRing();
|
|
191
|
+
container.appendChild(grid);
|
|
192
|
+
return {
|
|
193
|
+
update: (nextProps) => {
|
|
194
|
+
const needsRebuild = nextProps.challenge !== renderedChallenge || nextProps.themeColor !== props.themeColor;
|
|
195
|
+
props = nextProps;
|
|
196
|
+
if (needsRebuild) {
|
|
197
|
+
focusedHash = null;
|
|
198
|
+
rebuild();
|
|
199
|
+
}
|
|
200
|
+
applySelection();
|
|
201
|
+
applyFocusRing();
|
|
202
|
+
},
|
|
203
|
+
destroy: () => {
|
|
204
|
+
teardown.run();
|
|
205
|
+
grid.parentNode?.removeChild(grid);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
//#endregion
|
|
210
|
+
exports.mountCaptchaWidget = mountCaptchaWidget;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
|
|
2
|
+
let _prosopo_procaptcha = require("@prosopo/procaptcha");
|
|
3
|
+
//#region src/components/collector.ts
|
|
4
|
+
/**
|
|
5
|
+
* `startCollector` speaks the React setState shape (value or updater fn), so
|
|
6
|
+
* this adapts a plain array to it rather than changing the collector's
|
|
7
|
+
* signature — it is shared with the direct-consumer entry points.
|
|
8
|
+
*/
|
|
9
|
+
var arrayUpdater = (target) => {
|
|
10
|
+
return (update) => {
|
|
11
|
+
const next = "function" === typeof update ? update([...target]) : [...update];
|
|
12
|
+
target.length = 0;
|
|
13
|
+
target.push(...next);
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
var mountCollector = (container, initialProps) => {
|
|
17
|
+
let props = initialProps;
|
|
18
|
+
const mouseEvents = [];
|
|
19
|
+
const touchEvents = [];
|
|
20
|
+
const keyboardEvents = [];
|
|
21
|
+
const root = (0, _prosopo_procaptcha_common.createElement)("div");
|
|
22
|
+
container.appendChild(root);
|
|
23
|
+
(0, _prosopo_procaptcha.startCollector)(arrayUpdater(mouseEvents), arrayUpdater(touchEvents), arrayUpdater(keyboardEvents), root);
|
|
24
|
+
let lastAccount;
|
|
25
|
+
let lastOnProcessData;
|
|
26
|
+
const emit = () => {
|
|
27
|
+
if (props.account === lastAccount && props.onProcessData === lastOnProcessData) return;
|
|
28
|
+
lastAccount = props.account;
|
|
29
|
+
lastOnProcessData = props.onProcessData;
|
|
30
|
+
if (props.account) props.onProcessData({
|
|
31
|
+
mouseEvents,
|
|
32
|
+
touchEvents,
|
|
33
|
+
keyboardEvents
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
emit();
|
|
37
|
+
return {
|
|
38
|
+
update: (nextProps) => {
|
|
39
|
+
props = nextProps;
|
|
40
|
+
emit();
|
|
41
|
+
},
|
|
42
|
+
destroy: () => {
|
|
43
|
+
root.parentNode?.removeChild(root);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
exports.default = mountCollector;
|
|
49
|
+
exports.mountCollector = mountCollector;
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
const require_button = require("./button.cjs");
|
|
2
|
+
const require_modal = require("./modal.cjs");
|
|
3
|
+
const require_captchaWidget = require("./captchaWidget.cjs");
|
|
4
|
+
const require_captchaComponent = require("./captchaComponent.cjs");
|
|
5
|
+
const require_collector = require("./collector.cjs");
|
|
6
|
+
const require_procaptchaWidget = require("./procaptchaWidget.cjs");
|
|
7
|
+
const require_procaptcha = require("./procaptcha.cjs");
|
|
8
|
+
exports.loadProcaptcha = require_procaptcha.loadProcaptcha;
|
|
9
|
+
exports.mountButton = require_button.mountButton;
|
|
10
|
+
exports.mountCaptchaComponent = require_captchaComponent.mountCaptchaComponent;
|
|
11
|
+
exports.mountCaptchaWidget = require_captchaWidget.mountCaptchaWidget;
|
|
12
|
+
exports.mountCollector = require_collector.default;
|
|
13
|
+
exports.mountModal = require_modal.mountModal;
|
|
14
|
+
exports.mountProcaptcha = require_procaptcha.mountProcaptcha;
|
|
15
|
+
exports.mountProcaptchaImageWidget = require_procaptchaWidget.default;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
|
|
2
|
+
let _prosopo_widget_skeleton = require("@prosopo/widget-skeleton");
|
|
3
|
+
//#region src/components/modal.ts
|
|
4
|
+
var MIN_WRAPPER_DEPTH = 1;
|
|
5
|
+
var MAX_WRAPPER_DEPTH = 3;
|
|
6
|
+
/**
|
|
7
|
+
* The image captcha's dialog frame; positioning lives in `ChallengeSurface`.
|
|
8
|
+
*/
|
|
9
|
+
var mountModal = (initialProps) => {
|
|
10
|
+
const inner = (0, _prosopo_procaptcha_common.createElement)("div", { className: (0, _prosopo_widget_skeleton.randomToken)() });
|
|
11
|
+
(0, _prosopo_procaptcha_common.applyStyles)(inner, {
|
|
12
|
+
maxWidth: "500px",
|
|
13
|
+
maxHeight: "100%",
|
|
14
|
+
backgroundColor: "transparent",
|
|
15
|
+
border: "none",
|
|
16
|
+
borderRadius: "28px",
|
|
17
|
+
alignSelf: "center",
|
|
18
|
+
boxSizing: "border-box"
|
|
19
|
+
});
|
|
20
|
+
const outerClassName = (0, _prosopo_widget_skeleton.randomToken)();
|
|
21
|
+
const surfaceProps = (props) => ({
|
|
22
|
+
show: props.show,
|
|
23
|
+
placement: props.placement,
|
|
24
|
+
anchor: props.anchor,
|
|
25
|
+
onDismiss: props.onDismiss,
|
|
26
|
+
scrim: "none",
|
|
27
|
+
className: outerClassName,
|
|
28
|
+
dialogLabel: props.dialogLabel
|
|
29
|
+
});
|
|
30
|
+
const surface = (0, _prosopo_procaptcha_common.mountChallengeSurface)(surfaceProps(initialProps));
|
|
31
|
+
surface.content.appendChild((0, _prosopo_procaptcha_common.wrapRandomly)(inner, MIN_WRAPPER_DEPTH, MAX_WRAPPER_DEPTH));
|
|
32
|
+
return {
|
|
33
|
+
content: inner,
|
|
34
|
+
update: (props) => surface.update(surfaceProps(props)),
|
|
35
|
+
destroy: () => surface.destroy()
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
exports.mountModal = mountModal;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/components/procaptcha.ts
|
|
2
|
+
var loadProcaptcha = async () => (await Promise.resolve().then(() => require("./procaptchaWidget.cjs"))).mountProcaptchaImageWidget;
|
|
3
|
+
/**
|
|
4
|
+
* Mount without awaiting the chunk. Nothing renders until the import lands,
|
|
5
|
+
* matching `<Suspense>` with no fallback; destroying before then cancels the
|
|
6
|
+
* mount rather than leaving an orphan behind.
|
|
7
|
+
*/
|
|
8
|
+
var mountProcaptcha = (container, props) => {
|
|
9
|
+
let destroyed = false;
|
|
10
|
+
let inner;
|
|
11
|
+
loadProcaptcha().then((mount) => {
|
|
12
|
+
if (destroyed) return;
|
|
13
|
+
inner = mount(container, props);
|
|
14
|
+
});
|
|
15
|
+
return { destroy: () => {
|
|
16
|
+
destroyed = true;
|
|
17
|
+
inner?.destroy();
|
|
18
|
+
inner = void 0;
|
|
19
|
+
} };
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
exports.loadProcaptcha = loadProcaptcha;
|
|
23
|
+
exports.mountProcaptcha = mountProcaptcha;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const require_modal = require("./modal.cjs");
|
|
2
|
+
const require_captchaComponent = require("./captchaComponent.cjs");
|
|
3
|
+
let _prosopo_procaptcha_common = require("@prosopo/procaptcha-common");
|
|
4
|
+
let _prosopo_widget_skeleton = require("@prosopo/widget-skeleton");
|
|
5
|
+
let _prosopo_procaptcha = require("@prosopo/procaptcha");
|
|
6
|
+
let _prosopo_locale = require("@prosopo/locale");
|
|
7
|
+
let _prosopo_types = require("@prosopo/types");
|
|
8
|
+
//#region src/components/procaptchaWidget.ts
|
|
9
|
+
var PROCAPTCHA_EXECUTE_EVENT = "procaptcha:execute";
|
|
10
|
+
var mountProcaptchaImageWidget = (container, props) => {
|
|
11
|
+
const teardown = new _prosopo_procaptcha_common.Teardown();
|
|
12
|
+
const config = _prosopo_types.ProcaptchaConfigSchema.parse(props.config);
|
|
13
|
+
const frictionlessState = props.frictionlessState;
|
|
14
|
+
const i18n = props.i18n;
|
|
15
|
+
const callbacks = props.callbacks || {};
|
|
16
|
+
const translator = (0, _prosopo_locale.createTranslator)(i18n);
|
|
17
|
+
const isInvisible = "invisible" === config.mode;
|
|
18
|
+
const store = (0, _prosopo_procaptcha_common.createProcaptchaState)();
|
|
19
|
+
let loading = false;
|
|
20
|
+
let lastError = store.state.error;
|
|
21
|
+
let lastCoords = null;
|
|
22
|
+
let sessionInvalidatedFired = false;
|
|
23
|
+
let honeypot;
|
|
24
|
+
let captcha;
|
|
25
|
+
let checkbox;
|
|
26
|
+
const delegatesReload = Boolean(props.onReload);
|
|
27
|
+
const manager = (0, _prosopo_procaptcha.Manager)(config, store.state, store.update, callbacks, frictionlessState, () => honeypot?.getValue(), delegatesReload ? (x, y) => props.onReload?.(x, y) : void 0);
|
|
28
|
+
const root = (0, _prosopo_procaptcha_common.createElement)("div", { className: isInvisible ? void 0 : "image-captcha" });
|
|
29
|
+
container.appendChild(root);
|
|
30
|
+
if (frictionlessState?.hp) honeypot = (0, _prosopo_procaptcha_common.mountHoneypot)(root, { encodedQuestion: frictionlessState.hp });
|
|
31
|
+
const modalProps = () => ({
|
|
32
|
+
show: store.state.showModal,
|
|
33
|
+
placement: config.placement,
|
|
34
|
+
anchor: props.container,
|
|
35
|
+
onDismiss: manager.cancel,
|
|
36
|
+
dialogLabel: translator.t("WIDGET.IMAGE_DIALOG_LABEL", { defaultValue: "Image challenge" })
|
|
37
|
+
});
|
|
38
|
+
const modal = require_modal.mountModal(modalProps());
|
|
39
|
+
const emptyChallenge = (0, _prosopo_procaptcha_common.createElement)("div", { text: "No challenge set." });
|
|
40
|
+
const banner = isInvisible ? void 0 : (0, _prosopo_procaptcha_common.mountTestModeBanner)(root, { siteKey: config.account.address ?? "" });
|
|
41
|
+
const captchaProps = (challenge) => ({
|
|
42
|
+
challenge,
|
|
43
|
+
index: store.state.index,
|
|
44
|
+
solutions: store.state.solutions,
|
|
45
|
+
onSubmit: manager.submit,
|
|
46
|
+
onCancel: manager.cancel,
|
|
47
|
+
onClick: manager.select,
|
|
48
|
+
onNext: manager.nextRound,
|
|
49
|
+
onReload: manager.reload,
|
|
50
|
+
themeColor: config.theme ?? "light",
|
|
51
|
+
translator
|
|
52
|
+
});
|
|
53
|
+
const renderModal = () => {
|
|
54
|
+
modal.update(modalProps());
|
|
55
|
+
const challenge = store.state.challenge;
|
|
56
|
+
if (void 0 !== challenge) {
|
|
57
|
+
emptyChallenge.parentNode?.removeChild(emptyChallenge);
|
|
58
|
+
if (void 0 === captcha) captcha = require_captchaComponent.mountCaptchaComponent(modal.content, captchaProps(challenge));
|
|
59
|
+
else captcha.update(captchaProps(challenge));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
captcha?.destroy();
|
|
63
|
+
captcha = void 0;
|
|
64
|
+
if (!isInvisible && emptyChallenge.parentNode !== modal.content) modal.content.appendChild(emptyChallenge);
|
|
65
|
+
};
|
|
66
|
+
const runErrorEffect = () => {
|
|
67
|
+
if (store.state.error === lastError) return;
|
|
68
|
+
lastError = store.state.error;
|
|
69
|
+
if (!store.state.error) return;
|
|
70
|
+
loading = false;
|
|
71
|
+
if ("CAPTCHA.NO_SESSION_FOUND" !== store.state.error.key) return;
|
|
72
|
+
if (props.onSessionInvalidated && !sessionInvalidatedFired) {
|
|
73
|
+
sessionInvalidatedFired = true;
|
|
74
|
+
props.onSessionInvalidated(lastCoords?.x, lastCoords?.y);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (frictionlessState) {
|
|
78
|
+
const timer = setTimeout(() => {
|
|
79
|
+
frictionlessState.restart();
|
|
80
|
+
}, 100);
|
|
81
|
+
teardown.add(() => clearTimeout(timer));
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const render = () => {
|
|
85
|
+
runErrorEffect();
|
|
86
|
+
renderModal();
|
|
87
|
+
checkbox?.update(checkboxProps());
|
|
88
|
+
};
|
|
89
|
+
const scheduler = (0, _prosopo_procaptcha_common.createRenderScheduler)(render);
|
|
90
|
+
const checkboxProps = () => ({
|
|
91
|
+
theme: "light" === props.config.theme ? _prosopo_widget_skeleton.lightTheme : _prosopo_widget_skeleton.darkTheme,
|
|
92
|
+
checked: store.state.isHuman,
|
|
93
|
+
labelText: translator.isReady() ? translator.t("WIDGET.I_AM_HUMAN") : "",
|
|
94
|
+
error: store.state.error?.message,
|
|
95
|
+
loadingText: translator.t("WIDGET.CHECKING", { defaultValue: "Checking that you are human" }),
|
|
96
|
+
loading,
|
|
97
|
+
onChange: async (event) => {
|
|
98
|
+
if (!(0, _prosopo_procaptcha_common.isEventTrusted)(event)) return;
|
|
99
|
+
if (loading) return;
|
|
100
|
+
loading = true;
|
|
101
|
+
scheduler.schedule();
|
|
102
|
+
let x = 0;
|
|
103
|
+
let y = 0;
|
|
104
|
+
if ("clientX" in event && "clientY" in event) {
|
|
105
|
+
x = event.clientX;
|
|
106
|
+
y = event.clientY;
|
|
107
|
+
}
|
|
108
|
+
lastCoords = {
|
|
109
|
+
x,
|
|
110
|
+
y
|
|
111
|
+
};
|
|
112
|
+
try {
|
|
113
|
+
await manager.start(x, y);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error("Error starting verification:", error);
|
|
116
|
+
} finally {
|
|
117
|
+
loading = false;
|
|
118
|
+
scheduler.schedule();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
if (!isInvisible) checkbox = (0, _prosopo_procaptcha_common.mountCheckbox)(root, checkboxProps());
|
|
123
|
+
teardown.add(scheduler.cancel);
|
|
124
|
+
teardown.add(store.subscribe(scheduler.schedule));
|
|
125
|
+
teardown.add(translator.subscribe(scheduler.schedule));
|
|
126
|
+
const handleExecute = () => {
|
|
127
|
+
store.update({ showModal: true });
|
|
128
|
+
if (!store.state.challenge) {
|
|
129
|
+
console.log("No challenge set, attempting to start verification");
|
|
130
|
+
try {
|
|
131
|
+
manager.start();
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error("Error starting verification:", error);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
teardown.addEventListener(document, PROCAPTCHA_EXECUTE_EVENT, handleExecute);
|
|
138
|
+
if (props.container) teardown.addEventListener(props.container, PROCAPTCHA_EXECUTE_EVENT, handleExecute);
|
|
139
|
+
if (config.language) if (i18n) {
|
|
140
|
+
if (i18n.language !== config.language) i18n.changeLanguage(config.language);
|
|
141
|
+
} else (0, _prosopo_locale.loadI18next)(false, config.language);
|
|
142
|
+
if (props.autoStart) {
|
|
143
|
+
loading = true;
|
|
144
|
+
const coords = props.startCoords;
|
|
145
|
+
lastCoords = coords ?? null;
|
|
146
|
+
scheduler.schedule();
|
|
147
|
+
const clearLoading = () => {
|
|
148
|
+
loading = false;
|
|
149
|
+
scheduler.schedule();
|
|
150
|
+
};
|
|
151
|
+
manager.start(coords?.x ?? 0, coords?.y ?? 0).then(clearLoading, clearLoading);
|
|
152
|
+
}
|
|
153
|
+
render();
|
|
154
|
+
return { destroy: () => {
|
|
155
|
+
teardown.run();
|
|
156
|
+
captcha?.destroy();
|
|
157
|
+
modal.destroy();
|
|
158
|
+
checkbox?.destroy();
|
|
159
|
+
banner?.destroy();
|
|
160
|
+
honeypot?.destroy();
|
|
161
|
+
root.parentNode?.removeChild(root);
|
|
162
|
+
} };
|
|
163
|
+
};
|
|
164
|
+
//#endregion
|
|
165
|
+
exports.default = mountProcaptchaImageWidget;
|
|
166
|
+
exports.mountProcaptchaImageWidget = mountProcaptchaImageWidget;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
const require_button = require("./components/button.cjs");
|
|
3
|
+
const require_modal = require("./components/modal.cjs");
|
|
4
|
+
const require_captchaWidget = require("./components/captchaWidget.cjs");
|
|
5
|
+
const require_captchaComponent = require("./components/captchaComponent.cjs");
|
|
6
|
+
const require_collector = require("./components/collector.cjs");
|
|
7
|
+
const require_procaptchaWidget = require("./components/procaptchaWidget.cjs");
|
|
8
|
+
const require_procaptcha = require("./components/procaptcha.cjs");
|
|
9
|
+
exports.loadProcaptcha = require_procaptcha.loadProcaptcha;
|
|
10
|
+
exports.mountButton = require_button.mountButton;
|
|
11
|
+
exports.mountCaptchaComponent = require_captchaComponent.mountCaptchaComponent;
|
|
12
|
+
exports.mountCaptchaWidget = require_captchaWidget.mountCaptchaWidget;
|
|
13
|
+
exports.mountCollector = require_collector.default;
|
|
14
|
+
exports.mountModal = require_modal.mountModal;
|
|
15
|
+
exports.mountProcaptcha = require_procaptcha.mountProcaptcha;
|
|
16
|
+
exports.mountProcaptchaImageWidget = require_procaptchaWidget.default;
|
package/dist/cjs/util/index.cjs
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
//#region src/util/index.ts
|
|
2
2
|
function renameKeysForDataAttr(data = {}) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const renamed = {};
|
|
4
|
+
for (const key of Object.keys(data)) {
|
|
5
|
+
const value = data[key];
|
|
6
|
+
if (void 0 !== value) renamed[`data-${key}`] = value;
|
|
7
|
+
}
|
|
8
|
+
return renamed;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* maps any data to data attributes (mapped to { data-[key]: value })
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Component } from "@prosopo/procaptcha-common";
|
|
2
|
+
export interface ButtonProps {
|
|
3
|
+
themeColor: "light" | "dark";
|
|
4
|
+
buttonType: "cancel" | "next";
|
|
5
|
+
onClick: () => void;
|
|
6
|
+
text: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const mountButton: (container: HTMLElement, initialProps: ButtonProps) => Component<ButtonProps>;
|
|
9
|
+
//# sourceMappingURL=button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/components/button.ts"],"names":[],"mappings":"AAaA,OAAO,EACN,KAAK,SAAS,EAMd,MAAM,4BAA4B,CAAC;AAIpC,MAAM,WAAW,WAAW;IAC3B,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,UAAU,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACb;AA6BD,eAAO,MAAM,WAAW,cACZ,WAAW,gBACR,WAAW,KACvB,SAAS,CAAC,WAAW,CAiGvB,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import addDataAttr from "../util/index.js";
|
|
2
|
+
import { Teardown, applyAttributes, applyStyles, createControl } from "@prosopo/procaptcha-common";
|
|
3
|
+
import { darkTheme, lightTheme, withAlpha } from "@prosopo/widget-skeleton";
|
|
4
|
+
//#region src/components/button.ts
|
|
5
|
+
var buttonStyleBase = {
|
|
6
|
+
display: "inline-flex",
|
|
7
|
+
alignItems: "center",
|
|
8
|
+
justifyContent: "center",
|
|
9
|
+
position: "relative",
|
|
10
|
+
boxSizing: "border-box",
|
|
11
|
+
outline: "0px",
|
|
12
|
+
margin: "0px",
|
|
13
|
+
cursor: "pointer",
|
|
14
|
+
userSelect: "none",
|
|
15
|
+
verticalAlign: "middle",
|
|
16
|
+
textDecoration: "none",
|
|
17
|
+
textTransform: "none",
|
|
18
|
+
minWidth: "64px",
|
|
19
|
+
minHeight: "40px",
|
|
20
|
+
borderRadius: "100px",
|
|
21
|
+
border: "none",
|
|
22
|
+
transition: "background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, filter 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
|
|
23
|
+
backgroundColor: "transparent"
|
|
24
|
+
};
|
|
25
|
+
var mountButton = (container, initialProps) => {
|
|
26
|
+
const teardown = new Teardown();
|
|
27
|
+
let props = initialProps;
|
|
28
|
+
let hover = false;
|
|
29
|
+
let focusVisible = false;
|
|
30
|
+
const button = createControl(teardown, { onActivate: (event) => {
|
|
31
|
+
event.preventDefault();
|
|
32
|
+
props.onClick();
|
|
33
|
+
} });
|
|
34
|
+
const buttonStyle = () => {
|
|
35
|
+
const theme = "light" === props.themeColor ? lightTheme : darkTheme;
|
|
36
|
+
const baseStyle = {
|
|
37
|
+
...buttonStyleBase,
|
|
38
|
+
...theme.typography.labelLarge,
|
|
39
|
+
borderRadius: theme.shape.button,
|
|
40
|
+
fontFamily: theme.font.fontFamily,
|
|
41
|
+
width: "100%",
|
|
42
|
+
outline: focusVisible ? `3px solid ${theme.palette.primary.main}` : "0px",
|
|
43
|
+
outlineOffset: focusVisible ? "2px" : void 0
|
|
44
|
+
};
|
|
45
|
+
if ("cancel" === props.buttonType) return {
|
|
46
|
+
...baseStyle,
|
|
47
|
+
padding: "8px 12px",
|
|
48
|
+
backgroundColor: hover ? withAlpha(theme.palette.primary.main, theme.stateLayer.hover) : "transparent",
|
|
49
|
+
color: theme.palette.primary.main,
|
|
50
|
+
boxShadow: void 0
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
...baseStyle,
|
|
54
|
+
padding: "8px 24px",
|
|
55
|
+
backgroundColor: theme.palette.primary.main,
|
|
56
|
+
color: theme.palette.primary.contrastText,
|
|
57
|
+
boxShadow: hover ? `inset 0 0 0 100px ${withAlpha(theme.palette.primary.contrastText, theme.stateLayer.hover)}` : theme.elevation.buttonPrimary
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
const render = () => {
|
|
61
|
+
applyStyles(button, buttonStyle());
|
|
62
|
+
applyAttributes(button, {
|
|
63
|
+
...addDataAttr({ dev: { cy: `button-${props.buttonType}` } }),
|
|
64
|
+
"aria-label": props.text
|
|
65
|
+
});
|
|
66
|
+
button.textContent = props.text;
|
|
67
|
+
};
|
|
68
|
+
teardown.addEventListener(button, "mouseenter", () => {
|
|
69
|
+
hover = true;
|
|
70
|
+
render();
|
|
71
|
+
});
|
|
72
|
+
teardown.addEventListener(button, "mouseleave", () => {
|
|
73
|
+
hover = false;
|
|
74
|
+
render();
|
|
75
|
+
});
|
|
76
|
+
teardown.addEventListener(button, "focus", () => {
|
|
77
|
+
focusVisible = button.matches(":focus-visible");
|
|
78
|
+
render();
|
|
79
|
+
});
|
|
80
|
+
teardown.addEventListener(button, "blur", () => {
|
|
81
|
+
focusVisible = false;
|
|
82
|
+
render();
|
|
83
|
+
});
|
|
84
|
+
render();
|
|
85
|
+
container.appendChild(button);
|
|
86
|
+
return {
|
|
87
|
+
update: (nextProps) => {
|
|
88
|
+
props = nextProps;
|
|
89
|
+
render();
|
|
90
|
+
},
|
|
91
|
+
destroy: () => {
|
|
92
|
+
teardown.run();
|
|
93
|
+
button.parentNode?.removeChild(button);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
//#endregion
|
|
98
|
+
export { mountButton };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../src/components/button.ts"],"names":[],"mappings":"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"}
|