@spare-technologies/spare-link 1.0.0 → 1.1.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.
Files changed (74) hide show
  1. package/README.md +34 -5
  2. package/lib/commonjs/core/services/hosted-flow-controller.js +5 -0
  3. package/lib/commonjs/core/services/hosted-flow-controller.js.map +1 -1
  4. package/lib/commonjs/internal/bank-redirect.js +20 -9
  5. package/lib/commonjs/internal/bank-redirect.js.map +1 -1
  6. package/lib/commonjs/internal/hosted/bridge-message.js +13 -0
  7. package/lib/commonjs/internal/hosted/bridge-message.js.map +1 -1
  8. package/lib/commonjs/internal/telemetry/native-telemetry-reply.js +59 -0
  9. package/lib/commonjs/internal/telemetry/native-telemetry-reply.js.map +1 -0
  10. package/lib/commonjs/internal/telemetry/risk-telemetry-collector.js +99 -0
  11. package/lib/commonjs/internal/telemetry/risk-telemetry-collector.js.map +1 -0
  12. package/lib/commonjs/internal/telemetry/risk-telemetry-probes.js +134 -0
  13. package/lib/commonjs/internal/telemetry/risk-telemetry-probes.js.map +1 -0
  14. package/lib/commonjs/ui/hosted/hosted-payment-page.js +8 -0
  15. package/lib/commonjs/ui/hosted/hosted-payment-page.js.map +1 -1
  16. package/lib/commonjs/ui/hosted/hosted-payment-webview.js +31 -2
  17. package/lib/commonjs/ui/hosted/hosted-payment-webview.js.map +1 -1
  18. package/lib/commonjs/version.js +1 -1
  19. package/lib/module/core/services/hosted-flow-controller.js +5 -0
  20. package/lib/module/core/services/hosted-flow-controller.js.map +1 -1
  21. package/lib/module/internal/bank-redirect.js +20 -9
  22. package/lib/module/internal/bank-redirect.js.map +1 -1
  23. package/lib/module/internal/hosted/bridge-message.js +13 -0
  24. package/lib/module/internal/hosted/bridge-message.js.map +1 -1
  25. package/lib/module/internal/telemetry/native-telemetry-reply.js +53 -0
  26. package/lib/module/internal/telemetry/native-telemetry-reply.js.map +1 -0
  27. package/lib/module/internal/telemetry/risk-telemetry-collector.js +94 -0
  28. package/lib/module/internal/telemetry/risk-telemetry-collector.js.map +1 -0
  29. package/lib/module/internal/telemetry/risk-telemetry-probes.js +129 -0
  30. package/lib/module/internal/telemetry/risk-telemetry-probes.js.map +1 -0
  31. package/lib/module/ui/hosted/hosted-payment-page.js +8 -0
  32. package/lib/module/ui/hosted/hosted-payment-page.js.map +1 -1
  33. package/lib/module/ui/hosted/hosted-payment-webview.js +32 -3
  34. package/lib/module/ui/hosted/hosted-payment-webview.js.map +1 -1
  35. package/lib/module/version.js +1 -1
  36. package/lib/typescript/commonjs/core/services/hosted-flow-controller.d.ts.map +1 -1
  37. package/lib/typescript/commonjs/internal/bank-redirect.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts +12 -1
  39. package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts.map +1 -1
  40. package/lib/typescript/commonjs/internal/telemetry/native-telemetry-reply.d.ts +33 -0
  41. package/lib/typescript/commonjs/internal/telemetry/native-telemetry-reply.d.ts.map +1 -0
  42. package/lib/typescript/commonjs/internal/telemetry/risk-telemetry-collector.d.ts +47 -0
  43. package/lib/typescript/commonjs/internal/telemetry/risk-telemetry-collector.d.ts.map +1 -0
  44. package/lib/typescript/commonjs/internal/telemetry/risk-telemetry-probes.d.ts +19 -0
  45. package/lib/typescript/commonjs/internal/telemetry/risk-telemetry-probes.d.ts.map +1 -0
  46. package/lib/typescript/commonjs/ui/hosted/hosted-payment-page.d.ts.map +1 -1
  47. package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts +9 -0
  48. package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts.map +1 -1
  49. package/lib/typescript/commonjs/version.d.ts +1 -1
  50. package/lib/typescript/module/core/services/hosted-flow-controller.d.ts.map +1 -1
  51. package/lib/typescript/module/internal/bank-redirect.d.ts.map +1 -1
  52. package/lib/typescript/module/internal/hosted/bridge-message.d.ts +12 -1
  53. package/lib/typescript/module/internal/hosted/bridge-message.d.ts.map +1 -1
  54. package/lib/typescript/module/internal/telemetry/native-telemetry-reply.d.ts +33 -0
  55. package/lib/typescript/module/internal/telemetry/native-telemetry-reply.d.ts.map +1 -0
  56. package/lib/typescript/module/internal/telemetry/risk-telemetry-collector.d.ts +47 -0
  57. package/lib/typescript/module/internal/telemetry/risk-telemetry-collector.d.ts.map +1 -0
  58. package/lib/typescript/module/internal/telemetry/risk-telemetry-probes.d.ts +19 -0
  59. package/lib/typescript/module/internal/telemetry/risk-telemetry-probes.d.ts.map +1 -0
  60. package/lib/typescript/module/ui/hosted/hosted-payment-page.d.ts.map +1 -1
  61. package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts +9 -0
  62. package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts.map +1 -1
  63. package/lib/typescript/module/version.d.ts +1 -1
  64. package/package.json +24 -4
  65. package/plugins/with-spare-link.js +78 -5
  66. package/src/core/services/hosted-flow-controller.ts +5 -0
  67. package/src/internal/bank-redirect.ts +23 -9
  68. package/src/internal/hosted/bridge-message.ts +20 -1
  69. package/src/internal/telemetry/native-telemetry-reply.ts +59 -0
  70. package/src/internal/telemetry/risk-telemetry-collector.ts +128 -0
  71. package/src/internal/telemetry/risk-telemetry-probes.ts +159 -0
  72. package/src/ui/hosted/hosted-payment-page.tsx +8 -0
  73. package/src/ui/hosted/hosted-payment-webview.tsx +42 -4
  74. package/src/version.ts +1 -1
@@ -1,8 +1,10 @@
1
- import { useCallback, useEffect } from 'react';
1
+ import { useCallback, useEffect, useRef } from 'react';
2
2
  import { StyleSheet, View } from 'react-native';
3
3
  import { WebView, type WebViewMessageEvent } from 'react-native-webview';
4
+ import { parseHostedBridgeMessage } from '../../internal/hosted/bridge-message';
4
5
  import { buildHostedPaymentUrl, isHostedOriginUrl } from '../../internal/hosted/hosted-url';
5
6
  import { createLogger } from '../../internal/logger';
7
+ import { createTelemetryRequestHandler } from '../../internal/telemetry/native-telemetry-reply';
6
8
  import { parseUrlParts } from '../../internal/url-parts';
7
9
  import { Colors } from '../theme';
8
10
 
@@ -44,6 +46,15 @@ export interface HostedPaymentWebViewProps {
44
46
  * this component stays a transport.
45
47
  */
46
48
  onBridgeMessage: (message: unknown) => void;
49
+ /**
50
+ * Answers the page's telemetry request with this device's native risk facts.
51
+ *
52
+ * The reply travels back by injected script rather than a return value, so it
53
+ * is handled here where the webview reference lives, and the message never
54
+ * reaches [onBridgeMessage]. Absent, or answering null, means the page
55
+ * proceeds with what the browser alone can see.
56
+ */
57
+ onTelemetryRequest?: () => Promise<Record<string, unknown> | null>;
47
58
  /** Called when the page itself could not be loaded. */
48
59
  onLoadFailure?: () => void;
49
60
  /**
@@ -63,8 +74,10 @@ export interface HostedPaymentWebViewProps {
63
74
  * the page reports, and refuses to navigate anywhere else.
64
75
  */
65
76
  export function HostedPaymentWebView(props: HostedPaymentWebViewProps): JSX.Element {
66
- const { baseUrl, reference, onBridgeMessage, onLoadFailure, onMounted } = props;
77
+ const { baseUrl, reference, onBridgeMessage, onTelemetryRequest, onLoadFailure, onMounted } =
78
+ props;
67
79
  const uri = buildHostedPaymentUrl({ baseUrl, reference });
80
+ const webViewRef = useRef<WebView>(null);
68
81
 
69
82
  // This reports that *this* webview exists, and a retry mounts a fresh instance
70
83
  // which reports itself anew. Re-running on a new callback identity would
@@ -76,9 +89,23 @@ export function HostedPaymentWebView(props: HostedPaymentWebViewProps): JSX.Elem
76
89
 
77
90
  const handleMessage = useCallback(
78
91
  (event: WebViewMessageEvent) => {
79
- onBridgeMessage(event.nativeEvent.data);
92
+ const raw = event.nativeEvent.data;
93
+
94
+ // The telemetry request is answered here, where the webview reference
95
+ // lives, because the reply is delivered by injecting script — a channel
96
+ // only this component holds. Everything else stays the caller's.
97
+ if (onTelemetryRequest && parseHostedBridgeMessage(raw)?.type === 'telemetryRequest') {
98
+ const respond = createTelemetryRequestHandler({
99
+ collect: onTelemetryRequest,
100
+ inject: (script) => webViewRef.current?.injectJavaScript(script),
101
+ });
102
+ void respond();
103
+ return;
104
+ }
105
+
106
+ onBridgeMessage(raw);
80
107
  },
81
- [onBridgeMessage],
108
+ [onBridgeMessage, onTelemetryRequest],
82
109
  );
83
110
 
84
111
  // Every navigation is routed through here rather than through `originWhitelist`.
@@ -99,6 +126,7 @@ export function HostedPaymentWebView(props: HostedPaymentWebViewProps): JSX.Elem
99
126
  // modal, so this fills what it is given.
100
127
  <View style={styles.container} testID="hosted-payment-webview">
101
128
  <WebView
129
+ ref={webViewRef}
102
130
  source={{ uri }}
103
131
  onMessage={handleMessage}
104
132
  originWhitelist={ALLOW_ALL_ORIGINS}
@@ -141,6 +169,16 @@ export function HostedPaymentWebView(props: HostedPaymentWebViewProps): JSX.Elem
141
169
  style={styles.webview}
142
170
  javaScriptEnabled
143
171
  domStorageEnabled
172
+ // Lets the page's consent screen ask for a coarse location fix, which it
173
+ // attaches to the payment as a risk signal. Android only; iOS raises its
174
+ // own per-origin system prompt, gated by the host app's usage-description
175
+ // entry. This toggle is frame-wide — the platform offers no per-origin
176
+ // answer here — so the scope rests on `handleShouldStartLoad` above
177
+ // refusing every off-origin document in this frame. The toggle alone also
178
+ // reveals nothing: the host application must hold the user-facing location
179
+ // permission, and without it the page's request fails and the payment
180
+ // proceeds without the signal.
181
+ geolocationEnabled
144
182
  // The page holds a payment in progress and nothing else should share its
145
183
  // storage, on this device or between payers on it.
146
184
  incognito
package/src/version.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  * `changeset version`). The src/index.ts smoke test asserts this matches
7
7
  * package.json's version.
8
8
  */
9
- export const SDK_VERSION = '1.0.0' as const;
9
+ export const SDK_VERSION = '1.1.0' as const;