@prosopo/procaptcha-pow 2.10.9 → 2.10.11

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-pow@2.10.9 build:cjs
2
+ > @prosopo/procaptcha-pow@2.10.11 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -47,6 +47,6 @@ Build end
47
47
  rendering chunks...
48
48
  dist/cjs/index.cjs  0.25 kB
49
49
  dist/cjs/components/ProcaptchaPoW.cjs  0.70 kB
50
- dist/cjs/components/ProcaptchaWidget.cjs  3.98 kB
50
+ dist/cjs/components/ProcaptchaWidget.cjs  4.72 kB
51
51
  dist/cjs/services/Manager.cjs 10.31 kB
52
- ✓ built in 233ms
52
+ ✓ built in 241ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/procaptcha-pow@2.10.9 build:tsc
2
+ > @prosopo/procaptcha-pow@2.10.11 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 3:30:02 PM - Projects in this build:
5
+ 9:22:26 AM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../locale/tsconfig.json
8
8
  * ../util/tsconfig.json
@@ -20,37 +20,37 @@
20
20
  * ../procaptcha-common/tsconfig.json
21
21
  * tsconfig.json
22
22
 
23
- 3:30:02 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'
23
+ 9:22:27 AM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/vite/vite-plugin-fix-absolute-imports.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
24
24
 
25
- 3:30:02 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
25
+ 9:22:27 AM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/useTranslation.ts' is older than output '../locale/tsconfig.tsbuildinfo'
26
26
 
27
- 3:30:02 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
27
+ 9:22:27 AM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
28
28
 
29
- 3:30:03 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
+ 9:22:27 AM - 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
- 3:30:03 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
31
+ 9:22:27 AM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/provider/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
32
32
 
33
- 3:30:03 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
33
+ 9:22:27 AM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
34
34
 
35
- 3:30:03 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
35
+ 9:22:27 AM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
36
36
 
37
- 3:30:03 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/utils/batches.ts' is older than output '../common/tsconfig.tsbuildinfo'
37
+ 9:22:27 AM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
38
38
 
39
- 3:30:03 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
+ 9:22:27 AM - 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
- 3:30:03 PM - Project '../fingerprint/tsconfig.json' is up to date because newest input '../fingerprint/src/index.ts' is older than output '../fingerprint/tsconfig.tsbuildinfo'
41
+ 9:22:27 AM - 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
- 3:30:03 PM - Project '../load-balancer/tsconfig.json' is up to date because newest input '../load-balancer/src/index.ts' is older than output '../load-balancer/tsconfig.tsbuildinfo'
43
+ 9:22:27 AM - 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'
44
44
 
45
- 3:30:03 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'
45
+ 9:22:27 AM - 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'
46
46
 
47
- 3:30:03 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
47
+ 9:22:27 AM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/keyring/keyring.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
48
48
 
49
- 3:30:03 PM - Project '../account/tsconfig.json' is up to date because newest input '../account/src/custom.d.ts' is older than output '../account/tsconfig.tsbuildinfo'
49
+ 9:22:27 AM - Project '../account/tsconfig.json' is up to date because newest input '../account/src/index.ts' is older than output '../account/tsconfig.tsbuildinfo'
50
50
 
51
- 3:30:03 PM - Project '../procaptcha-common/tsconfig.json' is up to date because newest input '../procaptcha-common/src/tests/defaultEvents.test.ts' is older than output '../procaptcha-common/tsconfig.tsbuildinfo'
51
+ 9:22:27 AM - Project '../procaptcha-common/tsconfig.json' is up to date because newest input '../procaptcha-common/src/tests/defaultEvents.test.ts' is older than output '../procaptcha-common/tsconfig.tsbuildinfo'
52
52
 
53
- 3:30:03 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
53
+ 9:22:27 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
54
54
 
55
- 3:30:03 PM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-pow/tsconfig.json'...
55
+ 9:22:27 AM - Building project '/home/runner/work/captcha/captcha/packages/procaptcha-pow/tsconfig.json'...
56
56
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/procaptcha-pow@2.10.9 build
2
+ > @prosopo/procaptcha-pow@2.10.11 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/procaptcha-pow@2.10.9 build:cross-env
6
+ > @prosopo/procaptcha-pow@2.10.11 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -51,6 +51,6 @@ Build end
51
51
  rendering chunks...
52
52
  dist/index.js  0.13 kB
53
53
  dist/components/ProcaptchaPoW.js  0.33 kB
54
- dist/components/ProcaptchaWidget.js  3.84 kB
54
+ dist/components/ProcaptchaWidget.js  4.56 kB
55
55
  dist/services/Manager.js 10.15 kB
56
- ✓ built in 208ms
56
+ ✓ built in 201ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @prosopo/procaptcha-pow
2
2
 
3
+ ## 2.10.11
4
+ ### Patch Changes
5
+
6
+ - Updated dependencies [de12b31]
7
+ - Updated dependencies [770954b]
8
+ - @prosopo/types@4.9.4
9
+ - @prosopo/api@3.5.11
10
+ - @prosopo/fingerprint@2.7.10
11
+ - @prosopo/procaptcha-common@2.11.5
12
+
13
+ ## 2.10.10
14
+ ### Patch Changes
15
+
16
+ - 18d0287: fix(procaptcha-frictionless,procaptcha-pow,procaptcha-puzzle,procaptcha-react): auto-recover from `CAPTCHA.NO_SESSION_FOUND` on the inner widget without asking the user to click the checkbox a second time, and without dropping the click coordinates that would otherwise land in the solution salt as `(0, 0)`.
17
+
18
+ Motivation. The in-flight dedupe added in the previous change only collapses `/captcha/{type}` POSTs that overlap in flight. A duplicate POST that fires ~1 s after the first has already settled (observed on iPhone WKWebView, incident 2026-07-01 21:23 UTC) still lands on a consumed session and returns `NO_SESSION_FOUND`. The pre-existing recovery for that case was a `setTimeout(restart, 100)` that tore the whole widget down and lost the checkbox click position.
19
+
20
+ - `ProcaptchaProps` gains two optional props: `onSessionInvalidated(x?, y?)` and `startCoords: { x, y }`. Widgets not mounted under a recovery-aware parent still fall back to `frictionlessState.restart()`.
21
+ - `procaptcha-pow`, `procaptcha-puzzle`, and `procaptcha-react` widgets now track the last `manager.start(x, y)` coords in a ref (either from the checkbox click or from `startCoords`) and, on the first `CAPTCHA.NO_SESSION_FOUND`, invoke `onSessionInvalidated(x, y)` instead of calling `restart()`. A per-instance ref makes it strictly one-shot — a second failure falls back to the existing restart path so a persistently broken session doesn't loop.
22
+ - `ProcaptchaFrictionless` wires `onSessionInvalidated` through to each inner widget: it stashes the retry coords in a ref, re-runs its own `start()` (which re-invokes `/frictionless` and mints a fresh sessionId), then re-mounts the inner widget with `autoStart={true}` and `startCoords={x, y}`. The inner widget auto-fires `manager.start(x, y)` on mount so the eventual submit still embeds the real checkbox click position in the salt.
23
+ - The recovery decision (one-shot fire, coord validation — `(0, 0)` and partial pairs are discarded because they're what an `autoStart` mount or an untrusted pointer event emits rather than a real click, and the consume-and-clear pending-coords ref) is extracted into `sessionInvalidatedRecovery.ts` with dedicated unit tests.
24
+ - Updated dependencies [18d0287]
25
+ - @prosopo/types@4.9.3
26
+ - @prosopo/api@3.5.10
27
+ - @prosopo/fingerprint@2.7.9
28
+ - @prosopo/procaptcha-common@2.11.4
29
+
3
30
  ## 2.10.9
4
31
  ### Patch Changes
5
32
 
@@ -29,6 +29,8 @@ const Procaptcha = (props) => {
29
29
  () => hpRef.current?.value || void 0
30
30
  )
31
31
  );
32
+ const lastCoordsRef = react.useRef(null);
33
+ const sessionInvalidatedFiredRef = react.useRef(false);
32
34
  react.useEffect(() => {
33
35
  if (config.language) {
34
36
  if (i18n) {
@@ -44,15 +46,30 @@ const Procaptcha = (props) => {
44
46
  }
45
47
  }, [i18n, config.language]);
46
48
  react.useEffect(() => {
47
- if (state.error) {
49
+ if (!props.autoStart) return;
50
+ setLoading(true);
51
+ const coords = props.startCoords;
52
+ lastCoordsRef.current = coords ?? null;
53
+ manager.current.start(coords?.x ?? 0, coords?.y ?? 0).finally(() => {
48
54
  setLoading(false);
49
- if (state.error.key === "CAPTCHA.NO_SESSION_FOUND" && frictionlessState) {
50
- setTimeout(() => {
51
- frictionlessState.restart();
52
- }, 100);
53
- }
55
+ });
56
+ }, [props.autoStart, props.startCoords]);
57
+ react.useEffect(() => {
58
+ if (!state.error) return;
59
+ setLoading(false);
60
+ if (state.error.key !== "CAPTCHA.NO_SESSION_FOUND") return;
61
+ if (props.onSessionInvalidated && !sessionInvalidatedFiredRef.current) {
62
+ sessionInvalidatedFiredRef.current = true;
63
+ const coords = lastCoordsRef.current;
64
+ props.onSessionInvalidated(coords?.x, coords?.y);
65
+ return;
66
+ }
67
+ if (frictionlessState) {
68
+ setTimeout(() => {
69
+ frictionlessState.restart();
70
+ }, 100);
54
71
  }
55
- }, [state.error, frictionlessState]);
72
+ }, [state.error, frictionlessState, props.onSessionInvalidated]);
56
73
  react.useEffect(() => {
57
74
  if (config.mode === types.ModeEnum.invisible) {
58
75
  const handleExecuteEvent = (event) => {
@@ -100,6 +117,7 @@ const Procaptcha = (props) => {
100
117
  x = mouseOrTouchEvent.clientX;
101
118
  y = mouseOrTouchEvent.clientY;
102
119
  }
120
+ lastCoordsRef.current = { x, y };
103
121
  await manager.current.start(x, y);
104
122
  setLoading(false);
105
123
  },
@@ -1 +1 @@
1
- {"version":3,"file":"ProcaptchaWidget.d.ts","sourceRoot":"","sources":["../../src/components/ProcaptchaWidget.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAQhE,QAAA,MAAM,UAAU,UAAW,eAAe,4DAwIzC,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ProcaptchaWidget.d.ts","sourceRoot":"","sources":["../../src/components/ProcaptchaWidget.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAQhE,QAAA,MAAM,UAAU,UAAW,eAAe,4DAwKzC,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -28,6 +28,8 @@ const Procaptcha = (props) => {
28
28
  () => hpRef.current?.value || void 0
29
29
  )
30
30
  );
31
+ const lastCoordsRef = useRef(null);
32
+ const sessionInvalidatedFiredRef = useRef(false);
31
33
  useEffect(() => {
32
34
  if (config.language) {
33
35
  if (i18n) {
@@ -43,15 +45,30 @@ const Procaptcha = (props) => {
43
45
  }
44
46
  }, [i18n, config.language]);
45
47
  useEffect(() => {
46
- if (state.error) {
48
+ if (!props.autoStart) return;
49
+ setLoading(true);
50
+ const coords = props.startCoords;
51
+ lastCoordsRef.current = coords ?? null;
52
+ manager.current.start(coords?.x ?? 0, coords?.y ?? 0).finally(() => {
47
53
  setLoading(false);
48
- if (state.error.key === "CAPTCHA.NO_SESSION_FOUND" && frictionlessState) {
49
- setTimeout(() => {
50
- frictionlessState.restart();
51
- }, 100);
52
- }
54
+ });
55
+ }, [props.autoStart, props.startCoords]);
56
+ useEffect(() => {
57
+ if (!state.error) return;
58
+ setLoading(false);
59
+ if (state.error.key !== "CAPTCHA.NO_SESSION_FOUND") return;
60
+ if (props.onSessionInvalidated && !sessionInvalidatedFiredRef.current) {
61
+ sessionInvalidatedFiredRef.current = true;
62
+ const coords = lastCoordsRef.current;
63
+ props.onSessionInvalidated(coords?.x, coords?.y);
64
+ return;
65
+ }
66
+ if (frictionlessState) {
67
+ setTimeout(() => {
68
+ frictionlessState.restart();
69
+ }, 100);
53
70
  }
54
- }, [state.error, frictionlessState]);
71
+ }, [state.error, frictionlessState, props.onSessionInvalidated]);
55
72
  useEffect(() => {
56
73
  if (config.mode === ModeEnum.invisible) {
57
74
  const handleExecuteEvent = (event) => {
@@ -99,6 +116,7 @@ const Procaptcha = (props) => {
99
116
  x = mouseOrTouchEvent.clientX;
100
117
  y = mouseOrTouchEvent.clientY;
101
118
  }
119
+ lastCoordsRef.current = { x, y };
102
120
  await manager.current.start(x, y);
103
121
  setLoading(false);
104
122
  },
@@ -1 +1 @@
1
- {"version":3,"file":"ProcaptchaWidget.js","sourceRoot":"","sources":["../../src/components/ProcaptchaWidget.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ProcaptchaWidget.js","sourceRoot":"","sources":["../../src/components/ProcaptchaWidget.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosopo/procaptcha-pow",
3
- "version": "2.10.9",
3
+ "version": "2.10.11",
4
4
  "author": "PROSOPO LIMITED <info@prosopo.io>",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.js",
@@ -30,12 +30,12 @@
30
30
  "browserslist": ["> 0.5%, last 2 versions, not dead"],
31
31
  "dependencies": {
32
32
  "@polkadot/util": "13.5.7",
33
- "@prosopo/api": "3.5.9",
33
+ "@prosopo/api": "3.5.11",
34
34
  "@prosopo/common": "3.1.43",
35
- "@prosopo/fingerprint": "2.7.8",
35
+ "@prosopo/fingerprint": "2.7.10",
36
36
  "@prosopo/locale": "3.2.6",
37
- "@prosopo/procaptcha-common": "2.11.3",
38
- "@prosopo/types": "4.9.2",
37
+ "@prosopo/procaptcha-common": "2.11.5",
38
+ "@prosopo/types": "4.9.4",
39
39
  "@prosopo/util": "3.3.3",
40
40
  "@prosopo/util-crypto": "13.5.30",
41
41
  "@prosopo/widget-skeleton": "2.8.4",
@@ -46,6 +46,15 @@ const Procaptcha = (props: ProcaptchaProps) => {
46
46
  () => hpRef.current?.value || undefined,
47
47
  ),
48
48
  );
49
+ // Coordinates of the last `manager.start(x, y)` invocation from this widget
50
+ // instance — either the checkbox click, or a `startCoords` handoff from a
51
+ // prior `onSessionInvalidated` cycle. Held in a ref so the current values
52
+ // survive re-renders and are readable from the `state.error` effect.
53
+ const lastCoordsRef = useRef<{ x: number; y: number } | null>(null);
54
+ // One-shot guard: a widget instance only escalates a single NO_SESSION_FOUND
55
+ // to `onSessionInvalidated`. If the retry also fails, we fall through to
56
+ // the pre-existing `frictionlessState.restart()` path instead of looping.
57
+ const sessionInvalidatedFiredRef = useRef(false);
49
58
 
50
59
  useEffect(() => {
51
60
  if (config.language) {
@@ -63,15 +72,37 @@ const Procaptcha = (props: ProcaptchaProps) => {
63
72
  }, [i18n, config.language]);
64
73
 
65
74
  useEffect(() => {
66
- if (state.error) {
75
+ if (!props.autoStart) return;
76
+ setLoading(true);
77
+ const coords = props.startCoords;
78
+ lastCoordsRef.current = coords ?? null;
79
+ manager.current.start(coords?.x ?? 0, coords?.y ?? 0).finally(() => {
67
80
  setLoading(false);
68
- if (state.error.key === "CAPTCHA.NO_SESSION_FOUND" && frictionlessState) {
69
- setTimeout(() => {
70
- frictionlessState.restart();
71
- }, 100);
72
- }
81
+ });
82
+ }, [props.autoStart, props.startCoords]);
83
+
84
+ useEffect(() => {
85
+ if (!state.error) return;
86
+ setLoading(false);
87
+ if (state.error.key !== "CAPTCHA.NO_SESSION_FOUND") return;
88
+ if (props.onSessionInvalidated && !sessionInvalidatedFiredRef.current) {
89
+ // Preserve the checkbox coords across the retry so the resumed
90
+ // submit still carries the real entry-point telemetry. The
91
+ // frictionless wrapper mints a fresh session and re-mounts this
92
+ // widget with matching `autoStart` + `startCoords`.
93
+ sessionInvalidatedFiredRef.current = true;
94
+ const coords = lastCoordsRef.current;
95
+ props.onSessionInvalidated(coords?.x, coords?.y);
96
+ return;
97
+ }
98
+ if (frictionlessState) {
99
+ // Fallback for widgets not mounted under a recovery-aware parent,
100
+ // or a second NO_SESSION_FOUND after we've already retried once.
101
+ setTimeout(() => {
102
+ frictionlessState.restart();
103
+ }, 100);
73
104
  }
74
- }, [state.error, frictionlessState]);
105
+ }, [state.error, frictionlessState, props.onSessionInvalidated]);
75
106
 
76
107
  // Add event listener for the execute event (works for invisible mode)
77
108
  useEffect(() => {
@@ -149,6 +180,7 @@ const Procaptcha = (props: ProcaptchaProps) => {
149
180
  y = mouseOrTouchEvent.clientY;
150
181
  }
151
182
 
183
+ lastCoordsRef.current = { x, y };
152
184
  await manager.current.start(x, y);
153
185
  setLoading(false);
154
186
  }}