@prosopo/procaptcha-common 2.12.5 → 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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/procaptcha-common@2.12.5 build:cjs
2
+ > @prosopo/procaptcha-common@2.13.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: .
@@ -39,24 +39,25 @@ ViteCommonJSConfig: .
39
39
  vite v8.1.5 building ssr environment for production...
40
40
  Bundle build started
41
41
  
42
- 16 modules transformed.
42
+ 17 modules transformed.
43
43
  rendering chunks...
44
44
  computing gzip size...
45
- dist/cjs/extensionLoader.cjs 0.27 kB │ gzip: 0.16 kB
46
- dist/cjs/callbacks/defaultEvents.cjs 0.28 kB │ gzip: 0.16 kB
47
- dist/cjs/elements/form.cjs 0.62 kB │ gzip: 0.31 kB
48
- dist/cjs/simdReadings.cjs 0.79 kB │ gzip: 0.36 kB
49
- dist/cjs/clientMetaData.cjs 0.83 kB │ gzip: 0.47 kB
50
- dist/cjs/events/trust.cjs 0.91 kB │ gzip: 0.53 kB
51
- dist/cjs/elements/window.cjs 0.96 kB │ gzip: 0.54 kB
52
- dist/cjs/_virtual/_rolldown/runtime.cjs 1.00 kB │ gzip: 0.50 kB
53
- dist/cjs/reactComponents/TestModeBanner.cjs 1.36 kB │ gzip: 0.75 kB
54
- dist/cjs/providers.cjs 1.54 kB │ gzip: 0.64 kB
55
- dist/cjs/reactComponents/Honeypot.cjs 2.03 kB │ gzip: 0.91 kB
56
- dist/cjs/index.cjs 2.22 kB │ gzip: 0.59 kB
57
- dist/cjs/reactComponents/Reload.cjs 2.94 kB │ gzip: 1.30 kB
58
- dist/cjs/state/builder.cjs 3.13 kB │ gzip: 0.84 kB
59
- dist/cjs/callbacks/defaultCallbacks.cjs 3.84 kB │ gzip: 1.03 kB
60
- dist/cjs/reactComponents/Checkbox.cjs 5.39 kB │ gzip: 2.12 kB
45
+ dist/cjs/extensionLoader.cjs 0.27 kB │ gzip: 0.16 kB
46
+ dist/cjs/callbacks/defaultEvents.cjs 0.28 kB │ gzip: 0.16 kB
47
+ dist/cjs/elements/form.cjs 0.62 kB │ gzip: 0.31 kB
48
+ dist/cjs/simdReadings.cjs 0.79 kB │ gzip: 0.36 kB
49
+ dist/cjs/clientMetaData.cjs 0.83 kB │ gzip: 0.47 kB
50
+ dist/cjs/events/trust.cjs 0.91 kB │ gzip: 0.53 kB
51
+ dist/cjs/elements/window.cjs 0.96 kB │ gzip: 0.54 kB
52
+ dist/cjs/_virtual/_rolldown/runtime.cjs 1.00 kB │ gzip: 0.50 kB
53
+ dist/cjs/reactComponents/TestModeBanner.cjs 1.36 kB │ gzip: 0.75 kB
54
+ dist/cjs/providers.cjs 1.54 kB │ gzip: 0.64 kB
55
+ dist/cjs/reactComponents/Honeypot.cjs 2.03 kB │ gzip: 0.91 kB
56
+ dist/cjs/index.cjs 2.45 kB │ gzip: 0.63 kB
57
+ dist/cjs/reactComponents/Reload.cjs 2.94 kB │ gzip: 1.30 kB
58
+ dist/cjs/state/builder.cjs 3.13 kB │ gzip: 0.84 kB
59
+ dist/cjs/callbacks/defaultCallbacks.cjs 3.84 kB │ gzip: 1.03 kB
60
+ dist/cjs/reactComponents/Checkbox.cjs 5.39 kB │ gzip: 2.12 kB
61
+ dist/cjs/reactComponents/ChallengeSurface.cjs 5.84 kB │ gzip: 2.07 kB
61
62
 
62
- ✓ built in 39ms
63
+ ✓ built in 95ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/procaptcha-common@2.12.5 build:tsc
2
+ > @prosopo/procaptcha-common@2.13.0 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 1:56:29 PM - Projects in this build:
5
+ 1:15:26 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../locale/tsconfig.json
8
8
  * ../util/tsconfig.json
@@ -18,35 +18,35 @@
18
18
  * ../account/tsconfig.json
19
19
  * tsconfig.json
20
20
 
21
- 1:56:29 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'
21
+ 1:15:27 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'
22
22
 
23
- 1:56:29 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
23
+ 1:15:27 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
24
24
 
25
- 1:56:29 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
25
+ 1:15:27 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
26
26
 
27
- 1:56:29 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
27
+ 1:15:27 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
28
28
 
29
- 1:56:29 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
29
+ 1:15:27 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
30
30
 
31
- 1:56:29 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/index.ts' is older than output '../types/tsconfig.tsbuildinfo'
31
+ 1:15:27 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
32
32
 
33
- 1:56:29 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
33
+ 1:15:27 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/utils/batches.ts' is older than output '../common/tsconfig.tsbuildinfo'
34
34
 
35
- 1:56:29 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/balancer.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
35
+ 1:15:27 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/balancer.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
36
36
 
37
- 1:56:29 PM - Project '../widget-skeleton/tsconfig.json' is up to date because newest input '../widget-skeleton/src/constants.ts' is older than output '../widget-skeleton/tsconfig.tsbuildinfo'
37
+ 1:15:27 PM - Project '../widget-skeleton/tsconfig.json' is up to date because newest input '../widget-skeleton/src/index.ts' is older than output '../widget-skeleton/tsconfig.tsbuildinfo'
38
38
 
39
- 1:56:29 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/browser.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
39
+ 1:15:27 PM - Project '../fingerprintjs/tsconfig.json' is up to date because newest input '../fingerprintjs/src/utils/browser.ts' is older than output '../fingerprintjs/tsconfig.tsbuildinfo'
40
40
 
41
- 1:56:29 PM - Project '../fingerprint/tsconfig.json' is up to date because newest input '../fingerprint/src/index.ts' is older than output '../fingerprint/tsconfig.tsbuildinfo'
41
+ 1:15:27 PM - Project '../fingerprint/tsconfig.json' is up to date because newest input '../fingerprint/src/index.ts' is older than output '../fingerprint/tsconfig.tsbuildinfo'
42
42
 
43
- 1:56:29 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
43
+ 1:15:27 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/keyring/keyring.test.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
44
44
 
45
- 1:56:29 PM - Project '../account/tsconfig.json' is out of date because output file '../account/tsconfig.tsbuildinfo' does not exist
45
+ 1:15:27 PM - Project '../account/tsconfig.json' is out of date because output file '../account/tsconfig.tsbuildinfo' does not exist
46
46
 
47
- 1:56:29 PM - Building project '/home/runner/work/captcha/captcha/packages/account/tsconfig.json'...
47
+ 1:15:27 PM - Building project '/home/runner/work/captcha/captcha/packages/account/tsconfig.json'...
48
48
 
49
- 1:56:31 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
49
+ 1:15:30 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
50
50
 
51
- 1:56:31 PM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-common/tsconfig.json'...
51
+ 1:15:30 PM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-common/tsconfig.json'...
52
52
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/procaptcha-common@2.12.5 build
2
+ > @prosopo/procaptcha-common@2.13.0 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/procaptcha-common@2.12.5 build:cross-env
6
+ > @prosopo/procaptcha-common@2.13.0 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -43,24 +43,25 @@ ViteEsmConfig: .
43
43
  vite v8.1.5 building ssr environment for production...
44
44
  Bundle build started
45
45
  
46
- 16 modules transformed.
46
+ 17 modules transformed.
47
47
  rendering chunks...
48
48
  computing gzip size...
49
- dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
50
- dist/callbacks/defaultEvents.js 0.23 kB │ gzip: 0.15 kB
51
- dist/extensionLoader.js 0.25 kB │ gzip: 0.16 kB
52
- dist/elements/form.js 0.56 kB │ gzip: 0.30 kB
53
- dist/simdReadings.js 0.72 kB │ gzip: 0.35 kB
54
- dist/clientMetaData.js 0.81 kB │ gzip: 0.47 kB
55
- dist/events/trust.js 0.89 kB │ gzip: 0.52 kB
56
- dist/elements/window.js 0.91 kB │ gzip: 0.53 kB
57
- dist/reactComponents/TestModeBanner.js 1.23 kB │ gzip: 0.71 kB
58
- dist/index.js 1.35 kB │ gzip: 0.46 kB
59
- dist/providers.js 1.41 kB │ gzip: 0.62 kB
60
- dist/reactComponents/Honeypot.js 1.86 kB │ gzip: 0.89 kB
61
- dist/reactComponents/Reload.js 2.69 kB │ gzip: 1.26 kB
62
- dist/state/builder.js 3.09 kB │ gzip: 0.84 kB
63
- dist/callbacks/defaultCallbacks.js 3.64 kB │ gzip: 1.00 kB
64
- dist/reactComponents/Checkbox.js 4.87 kB │ gzip: 2.04 kB
49
+ dist/_virtual/_rolldown/runtime.js 0.04 kB │ gzip: 0.06 kB
50
+ dist/callbacks/defaultEvents.js 0.23 kB │ gzip: 0.15 kB
51
+ dist/extensionLoader.js 0.25 kB │ gzip: 0.16 kB
52
+ dist/elements/form.js 0.56 kB │ gzip: 0.30 kB
53
+ dist/simdReadings.js 0.72 kB │ gzip: 0.35 kB
54
+ dist/clientMetaData.js 0.81 kB │ gzip: 0.47 kB
55
+ dist/events/trust.js 0.89 kB │ gzip: 0.52 kB
56
+ dist/elements/window.js 0.91 kB │ gzip: 0.53 kB
57
+ dist/reactComponents/TestModeBanner.js 1.23 kB │ gzip: 0.71 kB
58
+ dist/providers.js 1.41 kB │ gzip: 0.62 kB
59
+ dist/index.js 1.49 kB │ gzip: 0.50 kB
60
+ dist/reactComponents/Honeypot.js 1.86 kB │ gzip: 0.89 kB
61
+ dist/reactComponents/Reload.js 2.69 kB │ gzip: 1.26 kB
62
+ dist/state/builder.js 3.09 kB │ gzip: 0.84 kB
63
+ dist/callbacks/defaultCallbacks.js 3.64 kB │ gzip: 1.00 kB
64
+ dist/reactComponents/Checkbox.js 4.87 kB │ gzip: 2.04 kB
65
+ dist/reactComponents/ChallengeSurface.js 5.52 kB │ gzip: 1.99 kB
65
66
 
66
- ✓ built in 385ms
67
+ ✓ built in 83ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # @prosopo/procaptcha-common
2
2
 
3
+ ## 2.13.0
4
+ ### Minor Changes
5
+
6
+ - d288371: Let a site choose where a challenge opens, and which button triggers it.
7
+
8
+ - `placement: "popup" | "float"`, also `data-placement`. `popup` is the default and unchanged. `float` opens the challenge directly above the widget and keeps it pinned there as the page scrolls, leaves the page usable behind it, and dismisses on Escape or an outside click. An invisible widget always uses popup.
9
+ - `bind: "#selector"`, also `data-bind`. The matching host-page button triggers that one widget, in visible or invisible mode. The click's default action is prevented so a submit button does not post the form before a token exists.
10
+ - `execute(widgetId?)`. Called with no argument every widget responds, as before. Called with the id `render()` returns, only that widget runs. Implicitly rendered invisible buttons now trigger only their own widget.
11
+
12
+ Behaviour changes for existing widgets:
13
+
14
+ - Escape now closes the image and puzzle challenge in both placements. For the image captcha this runs the cancel path, which fires `onClose` and restarts frictionless.
15
+ - Image and puzzle now present on one shared `ChallengeSurface`. Both were already portalled to `document.body`, so neither moves in the page, but the markup around them changed: the outer layer keeps `prosopo-modalOuter` for the image captcha and also carries `prosopo-challenge-surface`, and a new `prosopo-challenge-content` element sits between it and `prosopo-modalInner`. A direct-child selector such as `.prosopo-modalOuter > .prosopo-modalInner` no longer matches, and the centring transform now lives on `prosopo-challenge-content` rather than on `prosopo-modalInner`.
16
+
17
+ `createConfig` takes a named options object.
18
+
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies [6f57ee9]
22
+ - Updated dependencies [d288371]
23
+ - @prosopo/types@5.7.0
24
+ - @prosopo/account@2.8.88
25
+ - @prosopo/load-balancer@2.10.40
26
+
27
+ ## 2.12.6
28
+ ### Patch Changes
29
+
30
+ - 89dd38a: chore(deps): batch the outstanding dependabot bumps into one upgrade
31
+
32
+ Rolls up dependabot PRs #3112, #3127-#3134 and #3159. Majors: `mongoose`
33
+ 8 -> 9, `bson` 6 -> 7, `@noble/curves` 1 -> 2, `@polkadot/util-crypto`
34
+ 13 -> 14, `@typegoose/auto-increment` 4 -> 5, `@babel/preset-env` 7 -> 8,
35
+ `@types/jsdom` 21 -> 30, `@types/bcrypt` 5 -> 6, `@actions/github` 6 -> 9,
36
+ `testcontainers` 11 -> 12. The rest are minor/patch.
37
+
38
+ Code changes the majors forced:
39
+ - `@noble/curves` v2 requires `.js` specifiers and renamed the point API,
40
+ so `secp256k1.ProjectivePoint.fromHex(...).toRawBytes()` becomes
41
+ `secp256k1.Point.fromBytes(...).toBytes()`, `RistrettoPoint` becomes
42
+ `ristretto255.Point`, and `abstract/utils` moves to `utils.js`.
43
+ - mongoose 9 drops `RootFilterQuery` (now `QueryFilter`), no longer sets
44
+ `background: true` on schema indexes by default, and no longer declares
45
+ `id` on `Document`, which un-hid a mismatch between
46
+ `updateDappUserCommitment`'s `Hash` parameter and the `string` `id` it
47
+ filters on.
48
+ - mongoose 9 rejects an aggregation-pipeline update (an array) unless the
49
+ call passes `updatePipeline: true`, so the six pipeline writes in
50
+ `ProviderDatabase` now opt in explicitly.
51
+ - mongoose 9's `castUpdate` throws on a `$setOnInsert` key inside `$set`.
52
+ `storeUserImageCaptchaSolution` passed its record straight in as the
53
+ update, and mongoose's `moveImmutableProperties` mutates that object on
54
+ an upsert -- adding the very `$setOnInsert` key the record then carried
55
+ into `CentralDbStreamer.streamImageRecord`. Image records stopped
56
+ reaching the central DB (the streamer is fire-and-forget, so it only
57
+ logged) and signup verification returned 500. The update is now an
58
+ explicit `$set` over a shallow copy.
59
+ - `@prosopo/database` moves from mongodb 6.20 to 7.5 to match the driver
60
+ mongoose 9 pulls, so bson 7 is the only copy resolvable in the package.
61
+ - `vitest`/`@vitest/coverage-v8` go to 4.1.11 alongside dependabot's
62
+ `@vitest/spy` bump; leaving them at 4.1.10 installed a second copy of
63
+ `@vitest/spy` and broke type inference in the provider test utils.
64
+ - Updated dependencies [89dd38a]
65
+ - Updated dependencies [80f73c1]
66
+ - Updated dependencies [8a670d3]
67
+ - @prosopo/account@2.8.87
68
+ - @prosopo/load-balancer@2.10.39
69
+ - @prosopo/types@5.6.0
70
+ - @prosopo/widget-skeleton@2.8.7
71
+
3
72
  ## 2.12.5
4
73
  ### Patch Changes
5
74
 
@@ -10,8 +10,10 @@ const require_extensionLoader = require("./extensionLoader.cjs");
10
10
  const require_simdReadings = require("./simdReadings.cjs");
11
11
  const require_Reload = require("./reactComponents/Reload.cjs");
12
12
  const require_Checkbox = require("./reactComponents/Checkbox.cjs");
13
+ const require_ChallengeSurface = require("./reactComponents/ChallengeSurface.cjs");
13
14
  const require_Honeypot = require("./reactComponents/Honeypot.cjs");
14
15
  const require_TestModeBanner = require("./reactComponents/TestModeBanner.cjs");
16
+ exports.ChallengeSurface = require_ChallengeSurface.ChallengeSurface;
15
17
  exports.Checkbox = require_Checkbox.Checkbox;
16
18
  exports.ExtensionLoader = require_extensionLoader.ExtensionLoader;
17
19
  exports.Honeypot = require_Honeypot.Honeypot;
@@ -20,6 +22,7 @@ exports.SIMD_READINGS_SUBMIT_TIMEOUT_MS = require_simdReadings.SIMD_READINGS_SUB
20
22
  exports.TestModeBanner = require_TestModeBanner.TestModeBanner;
21
23
  exports.buildClientMetaData = require_clientMetaData.buildClientMetaData;
22
24
  exports.buildUpdateState = require_builder.buildUpdateState;
25
+ exports.computeFloatPosition = require_ChallengeSurface.computeFloatPosition;
23
26
  exports.getDefaultCallbacks = require_defaultCallbacks.getDefaultCallbacks;
24
27
  exports.getDefaultEvents = require_defaultEvents.getDefaultEvents;
25
28
  exports.getProcaptchaRandomActiveProvider = require_providers.getProcaptchaRandomActiveProvider;
@@ -0,0 +1,164 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ let _prosopo_types = require("@prosopo/types");
3
+ let react = require("react");
4
+ react = require_runtime.__toESM(react, 1);
5
+ let _emotion_react_jsx_runtime = require("@emotion/react/jsx-runtime");
6
+ let react_dom = require("react-dom");
7
+ //#region src/reactComponents/ChallengeSurface.tsx
8
+ var SURFACE_Z_INDEX = 2147483646;
9
+ var CONTENT_Z_INDEX = 2147483647;
10
+ var IOS_LIFT_STYLE_ID = "prosopo-challenge-surface-ios-lift";
11
+ var IOS_LIFT_CSS = `
12
+ .prosopo-challenge-content--ios-lift {
13
+ transform: translate(-50%, -50%);
14
+ }
15
+ @supports (-webkit-touch-callout: none) {
16
+ .prosopo-challenge-content--ios-lift {
17
+ transform: translate(-50%, -100%);
18
+ }
19
+ }
20
+ `;
21
+ var ensureIosLiftStyles = () => {
22
+ if (typeof document === "undefined") return;
23
+ if (document.getElementById(IOS_LIFT_STYLE_ID)) return;
24
+ const style = document.createElement("style");
25
+ style.id = IOS_LIFT_STYLE_ID;
26
+ style.textContent = IOS_LIFT_CSS;
27
+ document.head.appendChild(style);
28
+ };
29
+ var FLOAT_GAP_PX = 8;
30
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? react.useEffect : react.useLayoutEffect;
31
+ /**
32
+ * Places the panel directly above the anchor, in document coordinates.
33
+ *
34
+ * Document coordinates rather than viewport ones, because the panel is
35
+ * `position: absolute`: the page carries it while scrolling instead of the
36
+ * panel being recomputed against a moving viewport, which is what made it
37
+ * drift. Always above, never flipped, so the challenge does not jump to the
38
+ * other side of the widget as the page moves.
39
+ */
40
+ var computeFloatPosition = (anchorRect, panelHeight, scrollX, scrollY) => ({
41
+ top: Math.max(0, anchorRect.top + scrollY - panelHeight - FLOAT_GAP_PX),
42
+ left: anchorRect.left + scrollX
43
+ });
44
+ var ChallengeSurface = react.default.memo((props) => {
45
+ const { show, children, placement = _prosopo_types.PlacementEnum.popup, anchor, scrim = "none", onDismiss, popupIosLift = false, className } = props;
46
+ const contentRef = (0, react.useRef)(null);
47
+ const [floatPosition, setFloatPosition] = (0, react.useState)(null);
48
+ const isFloating = placement === _prosopo_types.PlacementEnum.float && !!anchor;
49
+ const reposition = (0, react.useCallback)(() => {
50
+ if (!isFloating || !anchor || !contentRef.current) return;
51
+ const panel = contentRef.current.getBoundingClientRect();
52
+ const next = computeFloatPosition(anchor.getBoundingClientRect(), panel.height, window.scrollX, window.scrollY);
53
+ setFloatPosition((current) => current && current.top === next.top && current.left === next.left ? current : next);
54
+ }, [isFloating, anchor]);
55
+ useIsomorphicLayoutEffect(() => {
56
+ if (!show || !isFloating) {
57
+ setFloatPosition(null);
58
+ return;
59
+ }
60
+ reposition();
61
+ }, [
62
+ show,
63
+ isFloating,
64
+ reposition
65
+ ]);
66
+ (0, react.useEffect)(() => {
67
+ if (!show || !isFloating) return;
68
+ window.addEventListener("resize", reposition);
69
+ const observer = typeof ResizeObserver === "function" ? new ResizeObserver(reposition) : null;
70
+ if (observer && contentRef.current) observer.observe(contentRef.current);
71
+ if (observer && anchor) observer.observe(anchor);
72
+ return () => {
73
+ window.removeEventListener("resize", reposition);
74
+ observer?.disconnect();
75
+ };
76
+ }, [
77
+ show,
78
+ isFloating,
79
+ anchor,
80
+ reposition
81
+ ]);
82
+ (0, react.useEffect)(() => {
83
+ if (!show || !onDismiss) return;
84
+ const onKeyDown = (event) => {
85
+ if (event.key === "Escape") onDismiss();
86
+ };
87
+ document.addEventListener("keydown", onKeyDown);
88
+ return () => document.removeEventListener("keydown", onKeyDown);
89
+ }, [show, onDismiss]);
90
+ (0, react.useEffect)(() => {
91
+ if (!show || !isFloating || !onDismiss) return;
92
+ const onPointerDown = (event) => {
93
+ const target = event.target;
94
+ if (!(target instanceof Node)) return;
95
+ if (contentRef.current?.contains(target)) return;
96
+ if (anchor?.contains(target)) return;
97
+ onDismiss();
98
+ };
99
+ document.addEventListener("pointerdown", onPointerDown);
100
+ return () => document.removeEventListener("pointerdown", onPointerDown);
101
+ }, [
102
+ show,
103
+ isFloating,
104
+ anchor,
105
+ onDismiss
106
+ ]);
107
+ (0, react.useEffect)(() => {
108
+ if (popupIosLift && !isFloating) ensureIosLiftStyles();
109
+ }, [popupIosLift, isFloating]);
110
+ if (typeof document === "undefined") return null;
111
+ const layerStyle = isFloating ? {
112
+ position: "absolute",
113
+ top: 0,
114
+ left: 0,
115
+ width: 0,
116
+ height: 0,
117
+ zIndex: SURFACE_Z_INDEX,
118
+ display: show ? "block" : "none",
119
+ pointerEvents: "none"
120
+ } : {
121
+ position: "fixed",
122
+ inset: 0,
123
+ zIndex: SURFACE_Z_INDEX,
124
+ display: show ? "flex" : "none",
125
+ alignItems: "center",
126
+ justifyContent: "center",
127
+ minHeight: "100vh",
128
+ backgroundColor: scrim === "dim" && show ? "rgba(0, 0, 0, 0.4)" : "transparent",
129
+ transition: "background-color 0.3s ease"
130
+ };
131
+ const contentStyle = isFloating ? {
132
+ position: "absolute",
133
+ zIndex: CONTENT_Z_INDEX,
134
+ pointerEvents: "auto",
135
+ top: `${floatPosition?.top ?? 0}px`,
136
+ left: `${floatPosition?.left ?? 0}px`,
137
+ visibility: floatPosition ? "visible" : "hidden"
138
+ } : {
139
+ position: "absolute",
140
+ top: "50%",
141
+ left: "50%",
142
+ transform: popupIosLift ? void 0 : "translate(-50%, -50%)",
143
+ zIndex: CONTENT_Z_INDEX,
144
+ boxSizing: "border-box"
145
+ };
146
+ return (0, react_dom.createPortal)(/* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)("div", {
147
+ className: [
148
+ "prosopo-challenge-surface",
149
+ `prosopo-challenge-surface--${isFloating ? "float" : "popup"}`,
150
+ className
151
+ ].filter(Boolean).join(" "),
152
+ style: layerStyle,
153
+ children: /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)("div", {
154
+ ref: contentRef,
155
+ className: popupIosLift && !isFloating ? "prosopo-challenge-content prosopo-challenge-content--ios-lift" : "prosopo-challenge-content",
156
+ style: contentStyle,
157
+ children
158
+ })
159
+ }), document.body);
160
+ });
161
+ ChallengeSurface.displayName = "ChallengeSurface";
162
+ //#endregion
163
+ exports.ChallengeSurface = ChallengeSurface;
164
+ exports.computeFloatPosition = computeFloatPosition;
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export * from "./simdReadings.js";
9
9
  export * from "./elements/window.js";
10
10
  export * from "./reactComponents/Reload.js";
11
11
  export * from "./reactComponents/Checkbox.js";
12
+ export * from "./reactComponents/ChallengeSurface.js";
12
13
  export * from "./reactComponents/Honeypot.js";
13
14
  export * from "./reactComponents/TestModeBanner.js";
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC"}
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ import { ExtensionLoader } from "./extensionLoader.js";
10
10
  import { SIMD_READINGS_SUBMIT_TIMEOUT_MS, getSimdReadingsForSubmit } from "./simdReadings.js";
11
11
  import { ReloadButton } from "./reactComponents/Reload.js";
12
12
  import { Checkbox } from "./reactComponents/Checkbox.js";
13
+ import { ChallengeSurface, computeFloatPosition } from "./reactComponents/ChallengeSurface.js";
13
14
  import { Honeypot } from "./reactComponents/Honeypot.js";
14
15
  import { TestModeBanner } from "./reactComponents/TestModeBanner.js";
15
- export { Checkbox, ExtensionLoader, Honeypot, ReloadButton, SIMD_READINGS_SUBMIT_TIMEOUT_MS, TestModeBanner, buildClientMetaData, buildUpdateState, getDefaultCallbacks, getDefaultEvents, getProcaptchaRandomActiveProvider, getRetryDelayMs, getSimdReadingsForSubmit, getWindowCallback, isEventTrusted, isSecureBrowserContext, pickIpMode, providerRetry, setUserCallbacks, useProcaptcha };
16
+ export { ChallengeSurface, Checkbox, ExtensionLoader, Honeypot, ReloadButton, SIMD_READINGS_SUBMIT_TIMEOUT_MS, TestModeBanner, buildClientMetaData, buildUpdateState, computeFloatPosition, getDefaultCallbacks, getDefaultEvents, getProcaptchaRandomActiveProvider, getRetryDelayMs, getSimdReadingsForSubmit, getWindowCallback, isEventTrusted, isSecureBrowserContext, pickIpMode, providerRetry, setUserCallbacks, useProcaptcha };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { type PlacementType } from "@prosopo/types";
2
+ import React, { type ReactNode } from "react";
3
+ export type SurfaceScrim = "none" | "dim";
4
+ interface ChallengeSurfaceProps {
5
+ show: boolean;
6
+ children: ReactNode;
7
+ placement?: PlacementType;
8
+ anchor?: HTMLElement | null;
9
+ scrim?: SurfaceScrim;
10
+ onDismiss?: () => void;
11
+ popupIosLift?: boolean;
12
+ className?: string;
13
+ }
14
+ interface FloatPosition {
15
+ top: number;
16
+ left: number;
17
+ }
18
+ declare const computeFloatPosition: (anchorRect: DOMRect, panelHeight: number, scrollX: number, scrollY: number) => FloatPosition;
19
+ declare const ChallengeSurface: React.MemoExoticComponent<(props: ChallengeSurfaceProps) => React.ReactPortal | null>;
20
+ export { ChallengeSurface, computeFloatPosition };
21
+ //# sourceMappingURL=ChallengeSurface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChallengeSurface.d.ts","sourceRoot":"","sources":["../../src/reactComponents/ChallengeSurface.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EAAE,EAEb,KAAK,SAAS,EAMd,MAAM,OAAO,CAAC;AAUf,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1C,UAAU,qBAAqB;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,YAAY,CAAC;IAErB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAEvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAkCD,UAAU,aAAa;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACb;AAWD,QAAA,MAAM,oBAAoB,eACb,OAAO,eACN,MAAM,WACV,MAAM,WACN,MAAM,KACb,aAKD,CAAC;AAEH,QAAA,MAAM,gBAAgB,oCAAsB,qBAAqB,8BA6K/D,CAAC;AAIH,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,CAAC"}