@checktiv/sdk-web 1.2.0 → 1.3.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/README.md +167 -77
- package/dist/{api-DyExBfAQ.d.ts → api-Dfn7oS9B.d.ts} +4 -0
- package/dist/chunk-MUCRC2QY.js +10 -0
- package/dist/custom-form.d.ts +1 -1
- package/dist/fraud.d.ts +1 -1
- package/dist/idv/cross-device.d.ts +1 -1
- package/dist/idv.d.ts +1 -1
- package/dist/index-Tv8a18sn.d.ts +34 -0
- package/dist/index.d.ts +5 -8
- package/dist/index.js +4 -9
- package/dist/react.d.ts +5 -24
- package/dist/react.js +5 -4
- package/dist/workspace.d.ts +1 -1
- package/package.json +3 -3
- package/dist/chunk-BEZGAQ74.js +0 -8
package/README.md
CHANGED
|
@@ -23,6 +23,80 @@ npm install @checktiv/sdk-web
|
|
|
23
23
|
`react` and `react-dom` are **optional peer dependencies**. Install them only if you
|
|
24
24
|
use the `./react` subpath. Everything else works without React.
|
|
25
25
|
|
|
26
|
+
## Quickstart
|
|
27
|
+
|
|
28
|
+
The recommended integration is the zero-lifecycle `mount()`. Your backend mints one
|
|
29
|
+
durable, low-privilege `clientToken` per applicant; the SDK exchanges it for
|
|
30
|
+
short-lived working tokens and refreshes them internally, so you write no
|
|
31
|
+
token-lifecycle code.
|
|
32
|
+
|
|
33
|
+
**Backend** - your server holds the secret key and returns a `clientToken`:
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
import { sessions } from '@checktiv/sdk-web';
|
|
37
|
+
|
|
38
|
+
// POST /kyc/session (your backend)
|
|
39
|
+
const { clientToken } = await sessions.create(
|
|
40
|
+
{ templateId: 'wt_...', applicant: { externalId: user.id } },
|
|
41
|
+
{
|
|
42
|
+
apiBase: 'https://api.us.checktiv.com',
|
|
43
|
+
secretKey: process.env.CHECKTIV_SECRET_KEY, // ah_sk_* - never in the browser
|
|
44
|
+
idempotencyKey: user.id, // retries and new-device re-entry never double-mint
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
// Return ONLY the clientToken to the browser.
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`sessions.create` throws if it runs in a browser: it needs your secret key, so call
|
|
51
|
+
it only from your server. The `clientToken` it returns can resume the applicant's own
|
|
52
|
+
session; it never reads verification results or applicant data.
|
|
53
|
+
|
|
54
|
+
**Frontend** - mount and forget:
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
import { mount } from '@checktiv/sdk-web';
|
|
58
|
+
import '@checktiv/sdk-web/idv'; // self-registers the managed IDV module
|
|
59
|
+
import '@checktiv/sdk-web/fraud'; // omit if the workflow never declares fraud
|
|
60
|
+
import '@checktiv/sdk-web/capture-ui/style.css'; // REQUIRED: styles the capture surface
|
|
61
|
+
|
|
62
|
+
const handle = mount(document.getElementById('checktiv-container'), {
|
|
63
|
+
publishableKey: 'ah_pk_us_test_...', // safe to expose - origin-pinned, no scopes
|
|
64
|
+
// Called ONCE for the cold start (or a new device), never on every expiry.
|
|
65
|
+
fetchToken: () =>
|
|
66
|
+
fetch('/kyc/session', { method: 'POST' })
|
|
67
|
+
.then((res) => res.json())
|
|
68
|
+
.then((data) => data.clientToken),
|
|
69
|
+
onConsent: () => showConsentPrompt(), // required only if the session declares fraud
|
|
70
|
+
onEvent: (event) => console.log(event),
|
|
71
|
+
onComplete: ({ sessionId }) => {
|
|
72
|
+
// Capture is complete. Wait for the webhook verdict before acting.
|
|
73
|
+
showMessage('Verification submitted. You will hear from us shortly.');
|
|
74
|
+
},
|
|
75
|
+
layout: 'immersive', // optional: full-screen capture on phones
|
|
76
|
+
theme: { primaryColor: '#0b5fff' }, // optional: match your brand
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Later, when navigating away:
|
|
80
|
+
// handle.destroy();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Key properties of this design:
|
|
84
|
+
|
|
85
|
+
- **No token-refresh code.** `fetchToken` fires once; the SDK mints and refreshes the
|
|
86
|
+
short-lived working token internally, so mid-flow expiry never surfaces to you.
|
|
87
|
+
- **Your secret key never touches client code.** Only `sessions.create` (server-side)
|
|
88
|
+
uses it; the browser holds just the low-privilege `clientToken`.
|
|
89
|
+
- **The server drives composition.** `mount()` renders whatever modules the session
|
|
90
|
+
declares (identity verification, the consent-gated fraud module, custom forms), so
|
|
91
|
+
you change the journey server-side without shipping new client code.
|
|
92
|
+
- **Import `@checktiv/sdk-web/capture-ui/style.css`.** The managed capture surface
|
|
93
|
+
ships its styles as a separate stylesheet; without this import the capture screen
|
|
94
|
+
renders unstyled and collapses to a small box.
|
|
95
|
+
|
|
96
|
+
`onComplete` (and `checktiv.idv.submitted`) means capture finished, not that
|
|
97
|
+
verification passed. The authoritative verdict arrives on your server as a signed
|
|
98
|
+
webhook.
|
|
99
|
+
|
|
26
100
|
## CDN usage
|
|
27
101
|
|
|
28
102
|
Load the moving pointer for the latest release:
|
|
@@ -46,19 +120,25 @@ release notes, so the exact bytes your page loads are locked and verified:
|
|
|
46
120
|
```
|
|
47
121
|
|
|
48
122
|
Use the region host that matches your account (for example `sdk.us.checktiv.com` or
|
|
49
|
-
`sdk.eu.checktiv.com`). The CDN bundle exposes the same API
|
|
50
|
-
|
|
123
|
+
`sdk.eu.checktiv.com`). The CDN bundle exposes the same API on the `window.Checktiv`
|
|
124
|
+
global and includes every module, so no per-module import is needed.
|
|
51
125
|
|
|
52
|
-
##
|
|
126
|
+
## Alternative: the per-request browser-token path (`init()`)
|
|
127
|
+
|
|
128
|
+
If your integration mints a fresh browser token on every page load instead of holding
|
|
129
|
+
a durable `clientToken`, use `init()` with a `getSessionToken` callback. `init()`
|
|
130
|
+
makes no network call; it sets up the client and the token callback, and
|
|
131
|
+
`mountProvisioned()` renders the server-declared modules.
|
|
53
132
|
|
|
54
133
|
```js
|
|
55
134
|
import { init } from '@checktiv/sdk-web';
|
|
56
|
-
import '@checktiv/sdk-web/idv';
|
|
135
|
+
import '@checktiv/sdk-web/idv';
|
|
136
|
+
import '@checktiv/sdk-web/capture-ui/style.css'; // REQUIRED for the managed capture surface
|
|
57
137
|
|
|
58
138
|
const client = init({
|
|
59
139
|
publishableKey: 'ah_pk_us_test_...',
|
|
60
140
|
getSessionToken: async (ctx) => {
|
|
61
|
-
// Your server
|
|
141
|
+
// Your server mints a short-lived browser token from its secret key.
|
|
62
142
|
const res = await fetch('/api/checktiv/token', {
|
|
63
143
|
method: 'POST',
|
|
64
144
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -66,96 +146,67 @@ const client = init({
|
|
|
66
146
|
});
|
|
67
147
|
return (await res.json()).token;
|
|
68
148
|
},
|
|
149
|
+
theme: { primaryColor: '#0b5fff' }, // optional
|
|
69
150
|
});
|
|
70
151
|
|
|
71
|
-
// Server-driven: renders whatever modules the session declares.
|
|
72
152
|
const handle = client.mountProvisioned({
|
|
73
153
|
target: document.getElementById('checktiv-container'),
|
|
74
154
|
onEvent: (event) => console.log(event),
|
|
75
155
|
});
|
|
76
|
-
|
|
77
|
-
// Later, when navigating away:
|
|
78
|
-
// handle.destroy();
|
|
156
|
+
// handle.destroy() when navigating away.
|
|
79
157
|
```
|
|
80
158
|
|
|
81
|
-
Key properties of this design:
|
|
82
|
-
|
|
83
|
-
- `init()` makes **no network call**. It only sets up the client and the token
|
|
84
|
-
callback.
|
|
85
|
-
- Your **secret key never touches client code**. `getSessionToken` returns a
|
|
86
|
-
short-lived browser token that your server mints; the SDK only ever holds that
|
|
87
|
-
token.
|
|
88
|
-
- **The server drives composition.** `mountProvisioned()` reads the modules the
|
|
89
|
-
session declares and renders each one, so you can change the journey server-side
|
|
90
|
-
without shipping new client code.
|
|
91
|
-
|
|
92
159
|
## Published subpaths
|
|
93
160
|
|
|
94
161
|
Every entry below is part of the published API. Import a module subpath (like
|
|
95
162
|
`./idv`) once anywhere in your app: importing it runs a one-time self-registration
|
|
96
|
-
side effect so `mountProvisioned()`
|
|
97
|
-
session needs a module you did not import, the SDK throws a clear,
|
|
98
|
-
telling you which subpath to add, instead of failing silently.
|
|
99
|
-
|
|
100
|
-
| Subpath | Purpose
|
|
101
|
-
| ------------------------- |
|
|
102
|
-
| `.` / `@checktiv/sdk-web` | Core entry: `
|
|
103
|
-
| `./idv` | Managed identity-verification module. Import for its self-registration side effect so `
|
|
104
|
-
| `./fraud` | Consent-gated fraud-signal collection. Import for its self-registration side effect.
|
|
105
|
-
| `./custom-form` | Custom intake-form module (server-authored field definitions). Import for its self-registration side effect.
|
|
106
|
-
| `./custom-form/style.css` | Stylesheet for the custom-form module. `<link>` or `import` this into the host page.
|
|
107
|
-
| `./
|
|
108
|
-
| `./
|
|
109
|
-
| `./capture
|
|
110
|
-
| `./
|
|
111
|
-
| `./
|
|
112
|
-
| `./
|
|
163
|
+
side effect so `mount()` / `mountProvisioned()` / `mount('idv')` can resolve that
|
|
164
|
+
module. If a session needs a module you did not import, the SDK throws a clear,
|
|
165
|
+
actionable error telling you which subpath to add, instead of failing silently.
|
|
166
|
+
|
|
167
|
+
| Subpath | Purpose |
|
|
168
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
169
|
+
| `.` / `@checktiv/sdk-web` | Core entry: the zero-lifecycle `mount(target, opts)` + `sessions.create`, plus the `init(opts)` client. Tree-shakeable and lightweight. |
|
|
170
|
+
| `./idv` | Managed identity-verification module. Import for its self-registration side effect so `mount()` / `mount('idv')` resolve it. |
|
|
171
|
+
| `./fraud` | Consent-gated fraud-signal collection. Import for its self-registration side effect. |
|
|
172
|
+
| `./custom-form` | Custom intake-form module (server-authored field definitions). Import for its self-registration side effect. |
|
|
173
|
+
| `./custom-form/style.css` | Stylesheet for the custom-form module. `<link>` or `import` this into the host page. |
|
|
174
|
+
| `./capture-ui/style.css` | Stylesheet for the managed IDV capture surface. Import it (the managed module renders through it) or the capture screen is unstyled. |
|
|
175
|
+
| `./react` | React wrappers: `ChecktivJourney` (zero-lifecycle `mount`), plus `ChecktivProvider` / `useChecktiv()` / `ChecktivIdv` (the `init()` path). |
|
|
176
|
+
| `./capture` | Advanced: headless host-side capture controller (`createCaptureController`). No default UI. |
|
|
177
|
+
| `./capture-ui` | Advanced: batteries-included capture renderer (`mount()`), built on `./capture`. |
|
|
178
|
+
| `./cross-device` | Cross-device QR / copy-link handoff overlay (`mountCrossDevice`). |
|
|
179
|
+
| `./idv/cross-device` | Cross-device wiring for the managed IDV module. |
|
|
180
|
+
| `./agents` | Machine-readable steering manifest (JSON) for coding-agent tooling. |
|
|
113
181
|
|
|
114
182
|
## Managed IDV module (`./idv`)
|
|
115
183
|
|
|
116
184
|
The managed IDV module renders the full identity-verification capture experience for
|
|
117
|
-
you. Import it for its registration side effect, then let
|
|
118
|
-
render it, or mount it explicitly:
|
|
185
|
+
you. Import it for its registration side effect and the capture stylesheet, then let
|
|
186
|
+
the provisioned session render it, or mount it explicitly on an `init()` client:
|
|
119
187
|
|
|
120
188
|
```js
|
|
121
|
-
import { init } from '@checktiv/sdk-web';
|
|
122
189
|
import '@checktiv/sdk-web/idv';
|
|
123
|
-
|
|
124
|
-
const client = init({ publishableKey: 'ah_pk_us_live_...', getSessionToken });
|
|
125
|
-
|
|
126
|
-
const idv = client.mount('idv', {
|
|
127
|
-
target: '#checktiv-container',
|
|
128
|
-
onEvent: (event) => {
|
|
129
|
-
// Events are named `checktiv.idv.*`, for example `checktiv.idv.ready`.
|
|
130
|
-
console.log(event.type);
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
// idv.destroy() when you are done.
|
|
190
|
+
import '@checktiv/sdk-web/capture-ui/style.css';
|
|
135
191
|
```
|
|
136
192
|
|
|
137
|
-
Events are `checktiv.<module>.<name
|
|
138
|
-
types can appear over time, so handle the ones you
|
|
139
|
-
do not write an exhaustive switch that assumes a
|
|
193
|
+
Events are `checktiv.<module>.<name>`, for example `checktiv.idv.ready`. The event
|
|
194
|
+
stream is forward-open: new event types can appear over time, so handle the ones you
|
|
195
|
+
care about and ignore the rest - do not write an exhaustive switch that assumes a
|
|
196
|
+
fixed set.
|
|
140
197
|
|
|
141
198
|
## Fraud module (`./fraud`)
|
|
142
199
|
|
|
143
200
|
Fraud-signal collection is **consent-gated and default-deny**: it collects nothing
|
|
144
|
-
until your `onConsent` callback resolves truthy.
|
|
201
|
+
until your `onConsent` callback resolves truthy. Pass `onConsent` to `mount()` (or to
|
|
202
|
+
`mount('fraud')` on an `init()` client) whenever the session declares the fraud
|
|
203
|
+
module.
|
|
145
204
|
|
|
146
205
|
```js
|
|
147
|
-
import { init } from '@checktiv/sdk-web';
|
|
148
206
|
import '@checktiv/sdk-web/fraud';
|
|
149
207
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const fraud = client.mount('fraud', {
|
|
153
|
-
target: '#checktiv-container',
|
|
154
|
-
onConsent: () => userHasConsented(), // boolean or Promise<boolean>
|
|
155
|
-
onEvent: (event) => console.log(event), // `checktiv.fraud.*`
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// fraud.destroy() when you are done.
|
|
208
|
+
// With mount(): pass onConsent in the mount options.
|
|
209
|
+
// onConsent: () => userHasConsented(), // boolean or Promise<boolean>
|
|
159
210
|
```
|
|
160
211
|
|
|
161
212
|
## Custom-form module (`./custom-form`)
|
|
@@ -171,19 +222,53 @@ import '@checktiv/sdk-web/custom-form/style.css';
|
|
|
171
222
|
|
|
172
223
|
The module always renders a continue control (even for a content-only screen) so the
|
|
173
224
|
journey can advance, and emits `checktiv.custom_form.submitted` when the applicant
|
|
174
|
-
completes it.
|
|
175
|
-
`customFormCopy` alongside `target`.
|
|
225
|
+
completes it. Pass `customFormConfig` and `customFormCopy` alongside `target`.
|
|
176
226
|
|
|
177
227
|
## React integration (`./react`)
|
|
178
228
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
229
|
+
`react` / `react-dom` are supplied by your app as optional peers, so there is a single
|
|
230
|
+
React instance. Both wrappers are SSR-safe (they render `null` on the server and only
|
|
231
|
+
initialize in the browser). Import the capture stylesheet alongside the modules.
|
|
232
|
+
|
|
233
|
+
### Recommended: `<ChecktivJourney>` (zero-lifecycle)
|
|
234
|
+
|
|
235
|
+
`<ChecktivJourney>` is the React wrapper for `mount()`. It needs no provider or
|
|
236
|
+
context: it manages the mount and teardown lifecycle for you (SSR-safe,
|
|
237
|
+
StrictMode-safe), and forwards every `mount()` option as a prop.
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
import { ChecktivJourney } from '@checktiv/sdk-web/react';
|
|
241
|
+
import '@checktiv/sdk-web/idv';
|
|
242
|
+
import '@checktiv/sdk-web/fraud';
|
|
243
|
+
import '@checktiv/sdk-web/capture-ui/style.css';
|
|
244
|
+
|
|
245
|
+
export function CheckIn() {
|
|
246
|
+
return (
|
|
247
|
+
<ChecktivJourney
|
|
248
|
+
publishableKey="ah_pk_us_test_..."
|
|
249
|
+
fetchToken={() => fetchClientToken()} // returns your durable clientToken
|
|
250
|
+
onConsent={() => showConsent()} // required only if the session declares fraud
|
|
251
|
+
onEvent={(e) => console.log(e)}
|
|
252
|
+
onComplete={({ sessionId }) => showDone(sessionId)}
|
|
253
|
+
layout="immersive" // optional: full-screen capture on phones
|
|
254
|
+
theme={{ primaryColor: '#0b5fff' }} // optional
|
|
255
|
+
/>
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Pass a `ref` to reach the in-SDK self-service resend (`ref.current.requestResend(email)`).
|
|
261
|
+
|
|
262
|
+
### The `init()` path: `<ChecktivProvider>` + `<ChecktivIdv>`
|
|
263
|
+
|
|
264
|
+
If you use the per-request browser-token flow (`init()` + `getSessionToken`), wrap
|
|
265
|
+
your tree in `<ChecktivProvider>` and render `<ChecktivIdv>`; `useChecktiv()` returns
|
|
266
|
+
the client from context.
|
|
183
267
|
|
|
184
268
|
```tsx
|
|
185
269
|
import { ChecktivProvider, ChecktivIdv } from '@checktiv/sdk-web/react';
|
|
186
|
-
import '@checktiv/sdk-web/idv';
|
|
270
|
+
import '@checktiv/sdk-web/idv';
|
|
271
|
+
import '@checktiv/sdk-web/capture-ui/style.css';
|
|
187
272
|
|
|
188
273
|
export function App() {
|
|
189
274
|
return (
|
|
@@ -197,8 +282,7 @@ export function App() {
|
|
|
197
282
|
}
|
|
198
283
|
```
|
|
199
284
|
|
|
200
|
-
`ChecktivIdv` mounts the managed IDV module and tears it down on unmount.
|
|
201
|
-
hosted developer docs for the full SSR-safe integration pattern.
|
|
285
|
+
`ChecktivIdv` mounts the managed IDV module and tears it down on unmount.
|
|
202
286
|
|
|
203
287
|
## Advanced: host-side capture (`./capture`, `./capture-ui`)
|
|
204
288
|
|
|
@@ -210,7 +294,8 @@ level escape hatches for hosts that need to own the capture surface themselves:
|
|
|
210
294
|
capture controller with no default UI. You inject token and submit functions and
|
|
211
295
|
drive the state machine yourself.
|
|
212
296
|
- `./capture-ui` exports `mount(element, options)`, a batteries-included default
|
|
213
|
-
renderer built on `./capture` that returns a `{ destroy }` handle.
|
|
297
|
+
renderer built on `./capture` that returns a `{ destroy }` handle. Import
|
|
298
|
+
`@checktiv/sdk-web/capture-ui/style.css` for its styles.
|
|
214
299
|
|
|
215
300
|
## Cross-device handoff (`./cross-device`)
|
|
216
301
|
|
|
@@ -234,7 +319,12 @@ migrating an older snippet:
|
|
|
234
319
|
The package ships self-contained type declarations. Import types from the root:
|
|
235
320
|
|
|
236
321
|
```ts
|
|
237
|
-
import type {
|
|
322
|
+
import type {
|
|
323
|
+
ChecktivClient,
|
|
324
|
+
ChecktivEvent,
|
|
325
|
+
ChecktivIdvEvent,
|
|
326
|
+
MountOptions,
|
|
327
|
+
} from '@checktiv/sdk-web';
|
|
238
328
|
```
|
|
239
329
|
|
|
240
330
|
The `ChecktivEvent` union is forward-open, so a handler typed against it keeps
|
|
@@ -270,6 +270,10 @@ type MountOptions = MountScope & {
|
|
|
270
270
|
readonly fetchImpl?: typeof fetch;
|
|
271
271
|
readonly resumeKey?: string;
|
|
272
272
|
readonly shortCode?: string;
|
|
273
|
+
readonly layout?: CaptureLayout;
|
|
274
|
+
readonly theme?: {
|
|
275
|
+
readonly primaryColor?: string;
|
|
276
|
+
};
|
|
273
277
|
};
|
|
274
278
|
interface SessionsCreateApplicant {
|
|
275
279
|
readonly externalId?: string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getModule } from './chunk-GFHNOZVO.js';
|
|
2
|
+
import { assertNever } from './chunk-UBQTPS5J.js';
|
|
3
|
+
import { createTokenManager, resolveSession, warnWrongTokenPlane, createChecktivError } from './chunk-QVDWM4KK.js';
|
|
4
|
+
import { R, k } from './chunk-XOGHMNBX.js';
|
|
5
|
+
import { resolveApiBaseOrigin, sdkPublicSettings, shortCodeRefreshPath, PUBLISHABLE_KEY_HEADER, SESSIONS_ME_REFRESH_LINK_PATH, WORKING_TOKEN_MINT_PATH } from './chunk-ITLSDZHK.js';
|
|
6
|
+
import { getServiceOrigin } from './chunk-QFA3K5ZV.js';
|
|
7
|
+
|
|
8
|
+
var PUBLISHABLE_KEY_REGEX=/^ah_pk_(us|eu)_(live|test)_[A-Za-z0-9_-]{8,}$/;var InvalidPublishableKeyError=class extends Error{constructor(message){super(message);this.name="InvalidPublishableKeyError";}};function parsePublishableKey(key){const match=PUBLISHABLE_KEY_REGEX.exec(key);if(!match){throw new InvalidPublishableKeyError(`Invalid publishable key format. Expected ah_pk_<us|eu>_<live|test>_<token>, got: ${maskKey(key)}`)}const region=match[1];const mode=match[2];if(region!=="us"&®ion!=="eu"){throw new InvalidPublishableKeyError(`Invalid region in publishable key: ${maskKey(key)}`)}if(mode!=="test"&&mode!=="live"){throw new InvalidPublishableKeyError(`Invalid mode in publishable key: ${maskKey(key)}`)}return {region,mode}}function maskKey(key){if(key.length<=8)return "***";return `${key.slice(0,6)}...${key.slice(-2)}`}var HOST_TAG="checktiv-root";var MOUNTED_FLAG="__checktivMounted";var LEGACY_HOST_ATTR="data-autohost-kyc-host";var HOST_ATTR="data-checktiv-host";var shadowCache=new WeakMap;function mountShadowHost(target){const existing=findExistingHost(target);if(existing){const cached=shadowCache.get(existing);if(cached)return cached}const host=document.createElement("div");host.setAttribute(HOST_ATTR,HOST_TAG);host.setAttribute(LEGACY_HOST_ATTR,HOST_TAG);host[MOUNTED_FLAG]=true;target.appendChild(host);const shadow=host.attachShadow({mode:"closed"});shadowCache.set(host,shadow);return shadow}function findExistingHost(target){for(const child of Array.from(target.children)){if(!(child instanceof HTMLElement))continue;const candidate=child;if(candidate[MOUNTED_FLAG]===true)return candidate}return null}function moduleErrorEvent(name,error){switch(name){case "idv":return {type:"checktiv.idv.error",error};case "fraud":return {type:"checktiv.fraud.error",error};case "custom_form":return {type:"checktiv.custom_form.error",error}}}function missingModuleMessage(name){return `This session requires the '${name}' module. Import '@checktiv/sdk-web/${name}' in your app.`}function missingModuleError(name){const base=createChecktivError("sdk_load_failed");return moduleErrorEvent(name,{...base,message:missingModuleMessage(name)})}function consentGateRequiredError(){const base=createChecktivError("sdk_load_failed");return moduleErrorEvent("fraud",{...base,message:"This session includes the 'fraud' module, which needs a consent gate. Pass onConsent to mountProvisioned() to enable it."})}function customFormConfigRequiredError(){const base=createChecktivError("sdk_load_failed");return moduleErrorEvent("custom_form",{...base,message:"This session includes the 'custom_form' module, which needs its form config. Pass customFormConfig to mountProvisioned() to enable it."})}function unmappedStepTypeError(stepType){const base=createChecktivError("sdk_load_failed");return moduleErrorEvent("idv",{...base,message:`This session's current step ('${stepType}') has no matching visual module in this SDK build. Upgrade '@checktiv/sdk-web' to a version that renders this step.`})}var MODULE_IS_VISUAL={idv:true,fraud:false,custom_form:true};var STEP_TYPE_TO_VISUAL_MODULE={id_verification:"idv",custom_form:"custom_form"};var stepTypeToVisualModuleView=STEP_TYPE_TO_VISUAL_MODULE;function resolveCurrentStepVisualModule(stepType){return stepTypeToVisualModuleView[stepType]}function defaultLoadModule(name){if(name==="idv"){const factory2=getModule("idv");if(factory2===void 0)return Promise.resolve(null);return Promise.resolve({mount:(ctx,opts)=>factory2(ctx,{target:opts.target,onEvent:opts.onEvent,copy:opts.copy,layout:opts.layout,onBeforeSubmit:opts.onBeforeSubmit,onBehaviorSegment:opts.onBehaviorSegment,synthetic:opts.synthetic})})}if(name==="custom_form"){const factory2=getModule("custom_form");if(factory2===void 0)return Promise.resolve(null);return Promise.resolve({mount:(ctx,opts)=>{if(opts.customFormConfig===void 0){opts.onEvent?.(customFormConfigRequiredError());return {destroy:()=>void 0}}return factory2(ctx,{target:opts.target,config:opts.customFormConfig,copy:opts.customFormCopy,onEvent:opts.onEvent,session:opts.session})}})}const factory=getModule("fraud");if(factory===void 0)return Promise.resolve(null);return Promise.resolve({mount:(ctx,opts)=>{const onConsent=opts.onConsent;if(onConsent===void 0){opts.onEvent?.(consentGateRequiredError());return {destroy:()=>void 0}}return factory(ctx,{onConsent,onEvent:opts.onEvent})}})}function moduleErrorFor(name,code){return moduleErrorEvent(name,createChecktivError(code))}function createMountProvisioned(ctx,opts,deps={}){const emit=e=>opts.onEvent?.(e);const fetchImpl=opts.fetchImpl??fetch;const resolveSession2=deps.resolveSession??(()=>resolveSession(ctx,fetchImpl));const loadModule=deps.loadModule??defaultLoadModule;const handles=[];let destroyed=false;void(async()=>{try{await composeModules();}catch(err){if(destroyed)return;console.warn("[Checktiv] mountProvisioned composition failed.",err);emit(moduleErrorFor("idv","sdk_load_failed"));}})();async function composeModules(){const resolution=await resolveSession2();if(destroyed)return;let session;switch(resolution.kind){case "ok":session=resolution.session;break;case "wrong_token":warnWrongTokenPlane();emit(moduleErrorFor("idv","wrong_token_type"));return;case "unresolved":emit(moduleErrorFor("idv","session_expired"));return;default:return assertNever(resolution)}const currentStepVisualModule=resolveCurrentStepVisualModule(session.stepType);if(currentStepVisualModule===void 0&&session.modules.some(m=>MODULE_IS_VISUAL[m])){emit(unmappedStepTypeError(session.stepType));return}for(const name of session.modules){if(destroyed)return;if(MODULE_IS_VISUAL[name]&&name!==currentStepVisualModule){continue}if(name==="fraud"&&opts.onConsent===void 0){emit(consentGateRequiredError());continue}const mod=await loadModule(name);if(destroyed)return;if(mod===null){emit(missingModuleError(name));continue}let moduleTarget;let containerToRemove=null;if(MODULE_IS_VISUAL[name]){const resolvedParent=typeof opts.target==="string"?typeof document!=="undefined"?document.querySelector(opts.target):null:opts.target;if(resolvedParent!==null){const container=document.createElement("div");resolvedParent.appendChild(container);containerToRemove=container;moduleTarget=container;}else {moduleTarget=opts.target;}}else {moduleTarget=opts.target;}let innerHandle;try{innerHandle=mod.mount(ctx,{target:moduleTarget,onEvent:opts.onEvent,onConsent:opts.onConsent,copy:opts.copy,layout:opts.layout,onBeforeSubmit:opts.onBeforeSubmit,onBehaviorSegment:opts.onBehaviorSegment,synthetic:opts.synthetic,customFormConfig:opts.customFormConfig,customFormCopy:opts.customFormCopy,session:{sessionId:session.sessionId,stepId:session.stepId}});}catch(err){containerToRemove?.remove();throw err}const capturedContainer=containerToRemove;const handle={destroy(){try{innerHandle.destroy();}finally{capturedContainer?.remove();}}};if(destroyed){handle.destroy();return}handles.push(handle);}}return {destroy(){destroyed=true;while(handles.length>0){const handle=handles.pop();handle?.destroy();}}}}function init(opts,deps={}){const scope="publishableKey"in opts?{...parsePublishableKey(opts.publishableKey),publishableKey:opts.publishableKey}:{region:opts.region,mode:opts.mode,publishableKey:void 0};let sessionId="";const apiBaseOrigin=resolveApiBaseOrigin(opts.apiBase,scope.region,scope.mode);const ctx={region:scope.region,mode:scope.mode,publishableKey:scope.publishableKey,apiBaseOrigin,theme:opts.theme,locale:opts.locale??"en",betas:opts.betas??[],...opts.selfiePromptMap!==void 0?{selfiePromptMap:opts.selfiePromptMap}:{},...opts.selfieChromeCopy!==void 0?{selfieChromeCopy:opts.selfieChromeCopy}:{},tokens:deps.tokens??createTokenManager(opts.getSessionToken,()=>sessionId),getSessionId:()=>sessionId,setSessionId:id=>{sessionId=id;}};function mount2(...args){if(args[0]==="idv"){const factory2=getModule("idv");if(factory2===void 0)return missingIdvHandle(args[1]);return factory2(ctx,args[1])}if(args[0]==="custom_form"){const factory2=getModule("custom_form");if(factory2===void 0)return missingCustomFormHandle(args[1]);return factory2(ctx,args[1])}const factory=getModule("fraud");if(factory===void 0)return missingFraudHandle(args[1]);return factory(ctx,args[1])}return {mountProvisioned:provOpts=>createMountProvisioned(ctx,provOpts),mount:mount2}}function missingIdvHandle(opts){const base=createChecktivError("sdk_load_failed");opts.onEvent?.({type:"checktiv.idv.error",error:{...base,message:missingModuleMessage("idv")}});return {destroy:()=>void 0,unmount:()=>void 0}}function missingFraudHandle(opts){const base=createChecktivError("sdk_load_failed");opts.onEvent?.({type:"checktiv.fraud.error",error:{...base,message:missingModuleMessage("fraud")}});return {destroy:()=>void 0}}function missingCustomFormHandle(opts){const base=createChecktivError("sdk_load_failed");const error={type:"checktiv.custom_form.error",error:{...base,message:missingModuleMessage("custom_form")}};opts.onEvent?.(error);return {destroy:()=>void 0}}var DEFAULT_REFRESH_MARGIN_MS=6e4;function createWorkingTokenManager(source,deps={}){const now=deps.now??(()=>Date.now());const setTimer=deps.setTimer??((fn,ms)=>setTimeout(fn,ms));const clearTimer=deps.clearTimer??(handle=>clearTimeout(handle));const marginMs=deps.marginMs??DEFAULT_REFRESH_MARGIN_MS;const onProactiveError=deps.onProactiveError;let cached=null;let pending=null;let timer=null;let stopped=false;const clearScheduled=()=>{if(timer!==null){clearTimer(timer);timer=null;}};const scheduleProactive=expiresAt=>{clearScheduled();if(stopped)return;const expiryMs=Date.parse(expiresAt);if(Number.isNaN(expiryMs))return;const delay=expiryMs-now()-marginMs;if(delay<=0)return;timer=setTimer(()=>{timer=null;void doRefresh("expired").catch(err=>onProactiveError?.(err));},delay);};const mintOnce=reason=>source(reason).then(minted=>{scheduleProactive(minted.expiresAt);return minted.token});const doRefresh=reason=>{if(pending!==null)return pending;const p=mintOnce(reason);pending=p;cached=p;void p.then(()=>{if(pending===p)pending=null;},()=>{if(pending===p)pending=null;if(cached===p)cached=null;});return p};return {get(){if(cached!==null)return cached;const p=mintOnce("initial");cached=p;void p.catch(()=>{if(cached===p)cached=null;});return p},refresh(reason){return doRefresh(reason)},stop(){stopped=true;clearScheduled();}}}var RESUME_CLIENT_TOKEN_KEY_PREFIX="checktiv.rct.";function safeLocalStorage(){try{return globalThis.localStorage??null}catch{return null}}function createClientTokenStore(resumeKey,storage=safeLocalStorage()){const key=RESUME_CLIENT_TOKEN_KEY_PREFIX+resumeKey;return {read(){if(storage===null)return null;try{const raw=storage.getItem(key);return raw!==null&&raw.length>0?raw:null}catch{return null}},write(token){if(storage===null)return;try{storage.setItem(key,token);}catch{}},clear(){if(storage===null)return;try{storage.removeItem(key);}catch{}}}}async function requestSelfServiceResend(params){const fetchImpl=params.fetchImpl??fetch;const body=JSON.stringify({confirmEmail:params.confirmEmail});try{let res;if(params.mode==="short_code"){res=await fetchImpl(params.origin+shortCodeRefreshPath(params.shortCode),{method:"POST",headers:{"content-type":"application/json"},body});}return {requested:res.ok}}catch{return {requested:false}}}var version="1.3.0";var initialised=new WeakSet;function resolveVerifyOrigin(parsed){return getServiceOrigin(sdkPublicSettings.apps.verify.subdomain,"prod",parsed.region,sdkPublicSettings)}function buildPopupUrl(parsed,opts){const origin=resolveVerifyOrigin(parsed);if(opts.applicantLinkToken){return `${origin}/start?lt=${encodeURIComponent(opts.applicantLinkToken)}`}return `${origin}/`}function launchPopup(url){const w=460;const h=760;const left=Math.max(0,Math.floor((window.screen.width-w)/2));const top=Math.max(0,Math.floor((window.screen.height-h)/2));const features=`popup=yes,width=${w},height=${h},left=${left},top=${top}`;const popup=window.open(url,"checktiv",features);if(!popup){window.location.href=url;return null}return popup}var COMPLETE_EVENT_TYPE="autohost.kyc.complete";function isCompletionMessage(data){if(typeof data!=="object"||data===null)return false;if(!("type"in data))return false;return data.type===COMPLETE_EVENT_TYPE}function listenForCompletion(expectedOrigin,onComplete){if(!onComplete)return;const handler=event=>{if(event.origin!==expectedOrigin)return;const data=event.data;if(!isCompletionMessage(data))return;onComplete(data);};window.addEventListener("message",handler);}function buildButton(onClick){const children="Start verification";return k("button",{type:"button",onClick,style:'display: inline-flex; align-items: center; justify-content: center; padding: 10px 20px; font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif; font-size: 14px; font-weight: 600; color: #fff; background: #0b5fff; border: none; border-radius: 6px; cursor: pointer;'},children)}function resolveTarget(opts){if(opts.target)return opts.target;return document.querySelector("[data-checktiv]")??document.querySelector("[data-autohost-kyc]")}function mountButton(opts){const parsed=parsePublishableKey(opts.publishableKey);const target=resolveTarget(opts);if(!target){console.warn("[Checktiv] No mount target found. Either pass `target` explicitly or add `<div data-checktiv>` to your page.");return}if(initialised.has(target))return;initialised.add(target);const shadow=mountShadowHost(target);const verifyOrigin=resolveVerifyOrigin(parsed);listenForCompletion(verifyOrigin,opts.onComplete);const onClick=()=>{const popupUrl=buildPopupUrl(parsed,opts);launchPopup(popupUrl);};R(buildButton(onClick),shadow);}function parseWorkingTokenMintResponse(body){if(typeof body!=="object"||body===null)return null;if(!("workingToken"in body)||!("expiresAt"in body))return null;const workingToken=body.workingToken;const expiresAt=body.expiresAt;if(typeof workingToken!=="string"||workingToken.length===0)return null;if(typeof expiresAt!=="string"||expiresAt.length===0)return null;return {workingToken,expiresAt}}async function mintWorkingTokenFacet(origin,clientToken,publishableKey,fetchImpl){const headers={Authorization:`Bearer ${clientToken}`};if(publishableKey!==void 0)headers[PUBLISHABLE_KEY_HEADER]=publishableKey;const res=await fetchImpl(origin+WORKING_TOKEN_MINT_PATH,{method:"POST",headers});if(!res.ok){throw new Error(`Checktiv working-token mint failed (status ${res.status}).`)}let body;try{body=await res.json();}catch{throw new Error("Checktiv working-token mint returned a non-JSON body.")}const parsed=parseWorkingTokenMintResponse(body);if(parsed===null)throw new Error("Checktiv working-token mint returned a malformed body.");return parsed}function completionSessionId(e){if(e.type!=="checktiv.idv.submitted"&&e.type!=="checktiv.custom_form.submitted"){return null}const sid="sessionId"in e?e.sessionId:void 0;return typeof sid==="string"&&sid.length>0?sid:null}function isSessionExpiredEvent(e){if(!e.type.endsWith(".error")||!("error"in e))return false;const err=e.error;if(typeof err!=="object"||err===null||!("code"in err))return false;return err.code==="session_expired"}function mount(target,opts){const fetchImpl=opts.fetchImpl??fetch;const scope="publishableKey"in opts?{...parsePublishableKey(opts.publishableKey),publishableKey:opts.publishableKey}:{region:opts.region,mode:opts.mode,publishableKey:void 0};const mintOrigin=resolveApiBaseOrigin(opts.apiBase,scope.region,scope.mode);const store=opts.resumeKey!==void 0?createClientTokenStore(opts.resumeKey):null;let clientTokenPromise=null;const getClientToken=()=>{if(clientTokenPromise!==null)return clientTokenPromise;const persisted=store?.read()??null;if(persisted!==null){clientTokenPromise=Promise.resolve(persisted);return clientTokenPromise}const p=opts.fetchToken();clientTokenPromise=p;void p.then(tok=>store?.write(tok),()=>{if(clientTokenPromise===p)clientTokenPromise=null;});return p};const mintWorkingToken=async()=>{const clientToken=await getClientToken();const minted=await mintWorkingTokenFacet(mintOrigin,clientToken,scope.publishableKey,fetchImpl);return {token:minted.workingToken,expiresAt:minted.expiresAt}};const tokens=createWorkingTokenManager(mintWorkingToken);const base={getSessionToken:()=>tokens.get(),...opts.apiBase!==void 0?{apiBase:opts.apiBase}:{},...opts.theme!==void 0?{theme:opts.theme}:{}};const initOptions=scope.publishableKey!==void 0?{...base,publishableKey:scope.publishableKey}:{...base,region:scope.region,mode:scope.mode};const needsChannel=opts.onEvent!==void 0||opts.onComplete!==void 0||store!==null;const onEvent=needsChannel?e=>{opts.onEvent?.(e);const sessionId=completionSessionId(e);if(sessionId!==null){store?.clear();opts.onComplete?.({sessionId});}else if(isSessionExpiredEvent(e)){store?.clear();}}:void 0;const client=init(initOptions,{tokens});const handle=client.mountProvisioned({target,fetchImpl,onEvent,onConsent:opts.onConsent,...opts.layout!==void 0?{layout:opts.layout}:{}});const requestResend=confirmEmail=>{if(opts.shortCode===void 0)return Promise.resolve({requested:false});return requestSelfServiceResend({mode:"short_code",origin:mintOrigin,shortCode:opts.shortCode,confirmEmail,fetchImpl})};return {destroy(){handle.destroy();tokens.stop();},requestResend}}function applicantToWire(a){const wire={};if(a.externalId!==void 0)wire.external_id=a.externalId;if(a.email!==void 0)wire.email=a.email;if(a.phone!==void 0)wire.phone=a.phone;if(a.firstName!==void 0)wire.first_name=a.firstName;if(a.lastName!==void 0)wire.last_name=a.lastName;if(a.dateOfBirth!==void 0)wire.date_of_birth=a.dateOfBirth;if(a.referenceName!==void 0)wire.reference_name=a.referenceName;return wire}function readCreatedClientToken(body){if(typeof body!=="object"||body===null||!("data"in body))return null;const data=body.data;if(typeof data!=="object"||data===null||!("client_token"in data))return null;const clientToken=data.client_token;return typeof clientToken==="string"&&clientToken.length>0?clientToken:null}var sessions={async create(input,options){if(typeof window!=="undefined"||typeof document!=="undefined"){throw new Error("checktiv.sessions.create must run on your server: it needs your secret key. Never call it in the browser.")}const fetchImpl=options.fetchImpl??fetch;const headers={Authorization:`Bearer ${options.secretKey}`,"content-type":"application/json"};if(options.idempotencyKey!==void 0)headers["Idempotency-Key"]=options.idempotencyKey;const body=JSON.stringify({workflow_template_id:input.templateId,applicant:applicantToWire(input.applicant)});const res=await fetchImpl(`${options.apiBase}/v1/sessions`,{method:"POST",headers,body});if(!res.ok){throw new Error(`Checktiv sessions.create failed (status ${res.status}). Verify the apiBase origin and secret key.`)}let parsed;try{parsed=await res.json();}catch{throw new Error("Checktiv sessions.create returned a non-JSON response.")}const clientToken=readCreatedClientToken(parsed);if(clientToken===null){throw new Error("Checktiv sessions.create response carried no client token. Enable the working-token capability for this environment, then retry.")}return {clientToken}}};
|
|
9
|
+
|
|
10
|
+
export { InvalidPublishableKeyError, init, mount, mountButton, parsePublishableKey, sessions, version };
|
package/dist/custom-form.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { E as ChecktivCustomFormEvent, H as CustomFormCopy, J as CustomFormFieldCopy, K as CustomFormHandle, L as CustomFormMountOptions, N as createCustomForm } from './api-
|
|
1
|
+
export { E as ChecktivCustomFormEvent, H as CustomFormCopy, J as CustomFormFieldCopy, K as CustomFormHandle, L as CustomFormMountOptions, N as createCustomForm } from './api-Dfn7oS9B.js';
|
|
2
2
|
import './machine-CuZalPFX.js';
|
|
3
3
|
import './copy-Dfmk11S_.js';
|
|
4
4
|
import './copy-DCeQ4JKx.js';
|
package/dist/fraud.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { f as ChecktivFraudEvent, F as FraudHandle, i as FraudMountOptions, O as createFraud } from './api-
|
|
1
|
+
export { f as ChecktivFraudEvent, F as FraudHandle, i as FraudMountOptions, O as createFraud } from './api-Dfn7oS9B.js';
|
|
2
2
|
import './machine-CuZalPFX.js';
|
|
3
3
|
import './copy-Dfmk11S_.js';
|
|
4
4
|
import './copy-DCeQ4JKx.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as SubstrateContext, h as CrossDeviceHandoffHook, g as ChecktivIdvEvent } from '../api-
|
|
1
|
+
import { A as SubstrateContext, h as CrossDeviceHandoffHook, g as ChecktivIdvEvent } from '../api-Dfn7oS9B.js';
|
|
2
2
|
import { C as CrossDeviceCopy } from '../copy-DCeQ4JKx.js';
|
|
3
3
|
import { CrossDevicePanelProps, CrossDeviceHandle } from '../cross-device.js';
|
|
4
4
|
import '../machine-CuZalPFX.js';
|
package/dist/idv.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import './machine-CuZalPFX.js';
|
|
2
2
|
import './copy-Dfmk11S_.js';
|
|
3
|
-
export { h as CrossDeviceHandoffHook, l as IdvHandle, m as IdvMountOptions, B as REMINT_READY_TIMEOUT_MS, D as createIdv } from './api-
|
|
3
|
+
export { h as CrossDeviceHandoffHook, l as IdvHandle, m as IdvMountOptions, B as REMINT_READY_TIMEOUT_MS, D as createIdv } from './api-Dfn7oS9B.js';
|
|
4
4
|
import './copy-DCeQ4JKx.js';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
import { g as ChecktivIdvEvent, M as MountOptions, C as ChecktivInitOptions, z as ChecktivInitScope, a as ChecktivClient } from './api-Dfn7oS9B.js';
|
|
4
|
+
import { C as CaptureLayout, a as CaptureBehaviorMessage } from './machine-CuZalPFX.js';
|
|
5
|
+
import { M as MountCopy } from './copy-Dfmk11S_.js';
|
|
6
|
+
|
|
7
|
+
interface SelfServiceResendResult {
|
|
8
|
+
readonly requested: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ChecktivProviderPropsBase {
|
|
12
|
+
getSessionToken: ChecktivInitOptions['getSessionToken'];
|
|
13
|
+
theme?: ChecktivInitOptions['theme'];
|
|
14
|
+
locale?: string;
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
}
|
|
17
|
+
type ChecktivProviderProps = ChecktivProviderPropsBase & ChecktivInitScope;
|
|
18
|
+
declare function ChecktivProvider(props: ChecktivProviderProps): ReactElement | null;
|
|
19
|
+
declare function useChecktiv(): ChecktivClient;
|
|
20
|
+
interface ChecktivIdvProps {
|
|
21
|
+
onEvent: (e: ChecktivIdvEvent) => void;
|
|
22
|
+
copy?: MountCopy;
|
|
23
|
+
layout?: CaptureLayout;
|
|
24
|
+
onBeforeSubmit?: () => Promise<void>;
|
|
25
|
+
onBehaviorSegment?: (segment: Pick<CaptureBehaviorMessage, 'steps' | 'traits'>) => void;
|
|
26
|
+
}
|
|
27
|
+
declare function ChecktivIdv({ onEvent, copy, layout, onBeforeSubmit, onBehaviorSegment, }: ChecktivIdvProps): ReactElement | null;
|
|
28
|
+
type ChecktivJourneyProps = MountOptions;
|
|
29
|
+
interface ChecktivJourneyHandle {
|
|
30
|
+
requestResend(confirmEmail: string): Promise<SelfServiceResendResult>;
|
|
31
|
+
}
|
|
32
|
+
declare const ChecktivJourney: react.ForwardRefExoticComponent<MountOptions & react.RefAttributes<ChecktivJourneyHandle>>;
|
|
33
|
+
|
|
34
|
+
export { type ChecktivIdvProps as C, type SelfServiceResendResult as S, type ChecktivJourneyHandle as a, type ChecktivJourneyProps as b, type ChecktivProviderProps as c, ChecktivIdv as d, ChecktivJourney as e, ChecktivProvider as f, type ChecktivProviderPropsBase as g, useChecktiv as u };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { C as ChecktivInitOptions, T as TokenManager, a as ChecktivClient, P as ProvisionedHandle, M as MountOptions, I as InitOptions, b as ChecktivSessions } from './api-
|
|
2
|
-
export { c as ChecktivError, d as ChecktivErrorCode, e as ChecktivEvent, f as ChecktivFraudEvent, g as ChecktivIdvEvent, h as CrossDeviceHandoffHook, F as FraudHandle, i as FraudMountOptions, G as GetSessionToken, j as GetSessionTokenContext, k as IdvCoachingHint, l as IdvHandle, m as IdvMountOptions, n as InvalidPublishableKeyError, o as MountCompleteResult, p as MountProvisionedOptions, q as MountScope, r as ParsedPublishableKey, R as ResolvedIdvConfig, S as SdkMode, s as SdkRegion, t as SessionsCreateApplicant, u as SessionsCreateInput, v as SessionsCreateOptions, w as SessionsCreateResult, x as SyntheticIdvScript, y as parsePublishableKey } from './api-
|
|
3
|
-
|
|
1
|
+
import { C as ChecktivInitOptions, T as TokenManager, a as ChecktivClient, P as ProvisionedHandle, M as MountOptions, I as InitOptions, b as ChecktivSessions } from './api-Dfn7oS9B.js';
|
|
2
|
+
export { c as ChecktivError, d as ChecktivErrorCode, e as ChecktivEvent, f as ChecktivFraudEvent, g as ChecktivIdvEvent, h as CrossDeviceHandoffHook, F as FraudHandle, i as FraudMountOptions, G as GetSessionToken, j as GetSessionTokenContext, k as IdvCoachingHint, l as IdvHandle, m as IdvMountOptions, n as InvalidPublishableKeyError, o as MountCompleteResult, p as MountProvisionedOptions, q as MountScope, r as ParsedPublishableKey, R as ResolvedIdvConfig, S as SdkMode, s as SdkRegion, t as SessionsCreateApplicant, u as SessionsCreateInput, v as SessionsCreateOptions, w as SessionsCreateResult, x as SyntheticIdvScript, y as parsePublishableKey } from './api-Dfn7oS9B.js';
|
|
3
|
+
import { S as SelfServiceResendResult } from './index-Tv8a18sn.js';
|
|
4
|
+
export { C as ChecktivIdvProps, a as ChecktivJourneyHandle, b as ChecktivJourneyProps, c as ChecktivProviderProps } from './index-Tv8a18sn.js';
|
|
4
5
|
import './machine-CuZalPFX.js';
|
|
5
6
|
import './copy-Dfmk11S_.js';
|
|
6
7
|
import './copy-DCeQ4JKx.js';
|
|
@@ -11,10 +12,6 @@ interface InitDeps {
|
|
|
11
12
|
}
|
|
12
13
|
declare function init(opts: ChecktivInitOptions, deps?: InitDeps): ChecktivClient;
|
|
13
14
|
|
|
14
|
-
interface SelfServiceResendResult {
|
|
15
|
-
readonly requested: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
15
|
declare const version: string;
|
|
19
16
|
declare function mountButton(opts: InitOptions): void;
|
|
20
17
|
interface MountHandle extends ProvisionedHandle {
|
|
@@ -23,4 +20,4 @@ interface MountHandle extends ProvisionedHandle {
|
|
|
23
20
|
declare function mount(target: HTMLElement | string, opts: MountOptions): MountHandle;
|
|
24
21
|
declare const sessions: ChecktivSessions;
|
|
25
22
|
|
|
26
|
-
export { ChecktivClient, ChecktivInitOptions, ChecktivSessions, InitOptions, type MountHandle, MountOptions, ProvisionedHandle,
|
|
23
|
+
export { ChecktivClient, ChecktivInitOptions, ChecktivSessions, InitOptions, type MountHandle, MountOptions, ProvisionedHandle, SelfServiceResendResult, init, mount, mountButton, sessions, version };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
export { InvalidPublishableKeyError, init, parsePublishableKey } from './chunk-BEZGAQ74.js';
|
|
1
|
+
export { InvalidPublishableKeyError, init, mount, mountButton, parsePublishableKey, sessions, version } from './chunk-MUCRC2QY.js';
|
|
3
2
|
import './chunk-GFHNOZVO.js';
|
|
4
3
|
import './chunk-UBQTPS5J.js';
|
|
5
4
|
import './chunk-QVDWM4KK.js';
|
|
6
|
-
import
|
|
5
|
+
import './chunk-XOGHMNBX.js';
|
|
7
6
|
import './chunk-IQKHRPJR.js';
|
|
8
|
-
import
|
|
9
|
-
import
|
|
7
|
+
import './chunk-ITLSDZHK.js';
|
|
8
|
+
import './chunk-QFA3K5ZV.js';
|
|
10
9
|
import './chunk-AIK7CDV6.js';
|
|
11
|
-
|
|
12
|
-
var HOST_TAG="checktiv-root";var MOUNTED_FLAG="__checktivMounted";var LEGACY_HOST_ATTR="data-autohost-kyc-host";var HOST_ATTR="data-checktiv-host";var shadowCache=new WeakMap;function mountShadowHost(target){const existing=findExistingHost(target);if(existing){const cached=shadowCache.get(existing);if(cached)return cached}const host=document.createElement("div");host.setAttribute(HOST_ATTR,HOST_TAG);host.setAttribute(LEGACY_HOST_ATTR,HOST_TAG);host[MOUNTED_FLAG]=true;target.appendChild(host);const shadow=host.attachShadow({mode:"closed"});shadowCache.set(host,shadow);return shadow}function findExistingHost(target){for(const child of Array.from(target.children)){if(!(child instanceof HTMLElement))continue;const candidate=child;if(candidate[MOUNTED_FLAG]===true)return candidate}return null}var DEFAULT_REFRESH_MARGIN_MS=6e4;function createWorkingTokenManager(source,deps={}){const now=deps.now??(()=>Date.now());const setTimer=deps.setTimer??((fn,ms)=>setTimeout(fn,ms));const clearTimer=deps.clearTimer??(handle=>clearTimeout(handle));const marginMs=deps.marginMs??DEFAULT_REFRESH_MARGIN_MS;const onProactiveError=deps.onProactiveError;let cached=null;let pending=null;let timer=null;let stopped=false;const clearScheduled=()=>{if(timer!==null){clearTimer(timer);timer=null;}};const scheduleProactive=expiresAt=>{clearScheduled();if(stopped)return;const expiryMs=Date.parse(expiresAt);if(Number.isNaN(expiryMs))return;const delay=expiryMs-now()-marginMs;if(delay<=0)return;timer=setTimer(()=>{timer=null;void doRefresh("expired").catch(err=>onProactiveError?.(err));},delay);};const mintOnce=reason=>source(reason).then(minted=>{scheduleProactive(minted.expiresAt);return minted.token});const doRefresh=reason=>{if(pending!==null)return pending;const p=mintOnce(reason);pending=p;cached=p;void p.then(()=>{if(pending===p)pending=null;},()=>{if(pending===p)pending=null;if(cached===p)cached=null;});return p};return {get(){if(cached!==null)return cached;const p=mintOnce("initial");cached=p;void p.catch(()=>{if(cached===p)cached=null;});return p},refresh(reason){return doRefresh(reason)},stop(){stopped=true;clearScheduled();}}}var RESUME_CLIENT_TOKEN_KEY_PREFIX="checktiv.rct.";function safeLocalStorage(){try{return globalThis.localStorage??null}catch{return null}}function createClientTokenStore(resumeKey,storage=safeLocalStorage()){const key=RESUME_CLIENT_TOKEN_KEY_PREFIX+resumeKey;return {read(){if(storage===null)return null;try{const raw=storage.getItem(key);return raw!==null&&raw.length>0?raw:null}catch{return null}},write(token){if(storage===null)return;try{storage.setItem(key,token);}catch{}},clear(){if(storage===null)return;try{storage.removeItem(key);}catch{}}}}async function requestSelfServiceResend(params){const fetchImpl=params.fetchImpl??fetch;const body=JSON.stringify({confirmEmail:params.confirmEmail});try{let res;if(params.mode==="short_code"){res=await fetchImpl(params.origin+shortCodeRefreshPath(params.shortCode),{method:"POST",headers:{"content-type":"application/json"},body});}return {requested:res.ok}}catch{return {requested:false}}}var version="1.2.0";var initialised=new WeakSet;function resolveVerifyOrigin(parsed){return getServiceOrigin(sdkPublicSettings.apps.verify.subdomain,"prod",parsed.region,sdkPublicSettings)}function buildPopupUrl(parsed,opts){const origin=resolveVerifyOrigin(parsed);if(opts.applicantLinkToken){return `${origin}/start?lt=${encodeURIComponent(opts.applicantLinkToken)}`}return `${origin}/`}function launchPopup(url){const w=460;const h=760;const left=Math.max(0,Math.floor((window.screen.width-w)/2));const top=Math.max(0,Math.floor((window.screen.height-h)/2));const features=`popup=yes,width=${w},height=${h},left=${left},top=${top}`;const popup=window.open(url,"checktiv",features);if(!popup){window.location.href=url;return null}return popup}var COMPLETE_EVENT_TYPE="autohost.kyc.complete";function isCompletionMessage(data){if(typeof data!=="object"||data===null)return false;if(!("type"in data))return false;return data.type===COMPLETE_EVENT_TYPE}function listenForCompletion(expectedOrigin,onComplete){if(!onComplete)return;const handler=event=>{if(event.origin!==expectedOrigin)return;const data=event.data;if(!isCompletionMessage(data))return;onComplete(data);};window.addEventListener("message",handler);}function buildButton(onClick){const children="Start verification";return k("button",{type:"button",onClick,style:'display: inline-flex; align-items: center; justify-content: center; padding: 10px 20px; font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif; font-size: 14px; font-weight: 600; color: #fff; background: #0b5fff; border: none; border-radius: 6px; cursor: pointer;'},children)}function resolveTarget(opts){if(opts.target)return opts.target;return document.querySelector("[data-checktiv]")??document.querySelector("[data-autohost-kyc]")}function mountButton(opts){const parsed=parsePublishableKey(opts.publishableKey);const target=resolveTarget(opts);if(!target){console.warn("[Checktiv] No mount target found. Either pass `target` explicitly or add `<div data-checktiv>` to your page.");return}if(initialised.has(target))return;initialised.add(target);const shadow=mountShadowHost(target);const verifyOrigin=resolveVerifyOrigin(parsed);listenForCompletion(verifyOrigin,opts.onComplete);const onClick=()=>{const popupUrl=buildPopupUrl(parsed,opts);launchPopup(popupUrl);};R(buildButton(onClick),shadow);}function parseWorkingTokenMintResponse(body){if(typeof body!=="object"||body===null)return null;if(!("workingToken"in body)||!("expiresAt"in body))return null;const workingToken=body.workingToken;const expiresAt=body.expiresAt;if(typeof workingToken!=="string"||workingToken.length===0)return null;if(typeof expiresAt!=="string"||expiresAt.length===0)return null;return {workingToken,expiresAt}}async function mintWorkingTokenFacet(origin,clientToken,publishableKey,fetchImpl){const headers={Authorization:`Bearer ${clientToken}`};if(publishableKey!==void 0)headers[PUBLISHABLE_KEY_HEADER]=publishableKey;const res=await fetchImpl(origin+WORKING_TOKEN_MINT_PATH,{method:"POST",headers});if(!res.ok){throw new Error(`Checktiv working-token mint failed (status ${res.status}).`)}let body;try{body=await res.json();}catch{throw new Error("Checktiv working-token mint returned a non-JSON body.")}const parsed=parseWorkingTokenMintResponse(body);if(parsed===null)throw new Error("Checktiv working-token mint returned a malformed body.");return parsed}function completionSessionId(e){if(e.type!=="checktiv.idv.submitted"&&e.type!=="checktiv.custom_form.submitted"){return null}const sid="sessionId"in e?e.sessionId:void 0;return typeof sid==="string"&&sid.length>0?sid:null}function isSessionExpiredEvent(e){if(!e.type.endsWith(".error")||!("error"in e))return false;const err=e.error;if(typeof err!=="object"||err===null||!("code"in err))return false;return err.code==="session_expired"}function mount(target,opts){const fetchImpl=opts.fetchImpl??fetch;const scope="publishableKey"in opts?{...parsePublishableKey(opts.publishableKey),publishableKey:opts.publishableKey}:{region:opts.region,mode:opts.mode,publishableKey:void 0};const mintOrigin=resolveApiBaseOrigin(opts.apiBase,scope.region,scope.mode);const store=opts.resumeKey!==void 0?createClientTokenStore(opts.resumeKey):null;let clientTokenPromise=null;const getClientToken=()=>{if(clientTokenPromise!==null)return clientTokenPromise;const persisted=store?.read()??null;if(persisted!==null){clientTokenPromise=Promise.resolve(persisted);return clientTokenPromise}const p=opts.fetchToken();clientTokenPromise=p;void p.then(tok=>store?.write(tok),()=>{if(clientTokenPromise===p)clientTokenPromise=null;});return p};const mintWorkingToken=async()=>{const clientToken=await getClientToken();const minted=await mintWorkingTokenFacet(mintOrigin,clientToken,scope.publishableKey,fetchImpl);return {token:minted.workingToken,expiresAt:minted.expiresAt}};const tokens=createWorkingTokenManager(mintWorkingToken);const base={getSessionToken:()=>tokens.get(),...opts.apiBase!==void 0?{apiBase:opts.apiBase}:{}};const initOptions=scope.publishableKey!==void 0?{...base,publishableKey:scope.publishableKey}:{...base,region:scope.region,mode:scope.mode};const needsChannel=opts.onEvent!==void 0||opts.onComplete!==void 0||store!==null;const onEvent=needsChannel?e=>{opts.onEvent?.(e);const sessionId=completionSessionId(e);if(sessionId!==null){store?.clear();opts.onComplete?.({sessionId});}else if(isSessionExpiredEvent(e)){store?.clear();}}:void 0;const client=init(initOptions,{tokens});const handle=client.mountProvisioned({target,fetchImpl,onEvent,onConsent:opts.onConsent});const requestResend=confirmEmail=>{if(opts.shortCode===void 0)return Promise.resolve({requested:false});return requestSelfServiceResend({mode:"short_code",origin:mintOrigin,shortCode:opts.shortCode,confirmEmail,fetchImpl})};return {destroy(){handle.destroy();tokens.stop();},requestResend}}function applicantToWire(a){const wire={};if(a.externalId!==void 0)wire.external_id=a.externalId;if(a.email!==void 0)wire.email=a.email;if(a.phone!==void 0)wire.phone=a.phone;if(a.firstName!==void 0)wire.first_name=a.firstName;if(a.lastName!==void 0)wire.last_name=a.lastName;if(a.dateOfBirth!==void 0)wire.date_of_birth=a.dateOfBirth;if(a.referenceName!==void 0)wire.reference_name=a.referenceName;return wire}function readCreatedClientToken(body){if(typeof body!=="object"||body===null||!("data"in body))return null;const data=body.data;if(typeof data!=="object"||data===null||!("client_token"in data))return null;const clientToken=data.client_token;return typeof clientToken==="string"&&clientToken.length>0?clientToken:null}var sessions={async create(input,options){if(typeof window!=="undefined"||typeof document!=="undefined"){throw new Error("checktiv.sessions.create must run on your server: it needs your secret key. Never call it in the browser.")}const fetchImpl=options.fetchImpl??fetch;const headers={Authorization:`Bearer ${options.secretKey}`,"content-type":"application/json"};if(options.idempotencyKey!==void 0)headers["Idempotency-Key"]=options.idempotencyKey;const body=JSON.stringify({workflow_template_id:input.templateId,applicant:applicantToWire(input.applicant)});const res=await fetchImpl(`${options.apiBase}/v1/sessions`,{method:"POST",headers,body});if(!res.ok){throw new Error(`Checktiv sessions.create failed (status ${res.status}). Verify the apiBase origin and secret key.`)}let parsed;try{parsed=await res.json();}catch{throw new Error("Checktiv sessions.create returned a non-JSON response.")}const clientToken=readCreatedClientToken(parsed);if(clientToken===null){throw new Error("Checktiv sessions.create response carried no client token. Enable the working-token capability for this environment, then retry.")}return {clientToken}}};
|
|
13
|
-
|
|
14
|
-
export { mount, mountButton, sessions, version };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,25 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import 'react';
|
|
2
|
+
import './api-Dfn7oS9B.js';
|
|
3
|
+
import './machine-CuZalPFX.js';
|
|
4
|
+
import './copy-Dfmk11S_.js';
|
|
5
|
+
export { d as ChecktivIdv, C as ChecktivIdvProps, e as ChecktivJourney, a as ChecktivJourneyHandle, b as ChecktivJourneyProps, f as ChecktivProvider, c as ChecktivProviderProps, g as ChecktivProviderPropsBase, u as useChecktiv } from './index-Tv8a18sn.js';
|
|
5
6
|
import './copy-DCeQ4JKx.js';
|
|
6
|
-
|
|
7
|
-
interface ChecktivProviderPropsBase {
|
|
8
|
-
getSessionToken: ChecktivInitOptions['getSessionToken'];
|
|
9
|
-
theme?: ChecktivInitOptions['theme'];
|
|
10
|
-
locale?: string;
|
|
11
|
-
children: ReactNode;
|
|
12
|
-
}
|
|
13
|
-
type ChecktivProviderProps = ChecktivProviderPropsBase & ChecktivInitScope;
|
|
14
|
-
declare function ChecktivProvider(props: ChecktivProviderProps): ReactElement | null;
|
|
15
|
-
declare function useChecktiv(): ChecktivClient;
|
|
16
|
-
interface ChecktivIdvProps {
|
|
17
|
-
onEvent: (e: ChecktivIdvEvent) => void;
|
|
18
|
-
copy?: MountCopy;
|
|
19
|
-
layout?: CaptureLayout;
|
|
20
|
-
onBeforeSubmit?: () => Promise<void>;
|
|
21
|
-
onBehaviorSegment?: (segment: Pick<CaptureBehaviorMessage, 'steps' | 'traits'>) => void;
|
|
22
|
-
}
|
|
23
|
-
declare function ChecktivIdv({ onEvent, copy, layout, onBeforeSubmit, onBehaviorSegment, }: ChecktivIdvProps): ReactElement | null;
|
|
24
|
-
|
|
25
|
-
export { ChecktivIdv, type ChecktivIdvProps, ChecktivProvider, type ChecktivProviderProps, type ChecktivProviderPropsBase, useChecktiv };
|
package/dist/react.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { init } from './chunk-
|
|
1
|
+
import { mount, init } from './chunk-MUCRC2QY.js';
|
|
2
2
|
import './chunk-GFHNOZVO.js';
|
|
3
3
|
import './chunk-UBQTPS5J.js';
|
|
4
4
|
import './chunk-QVDWM4KK.js';
|
|
5
|
+
import './chunk-XOGHMNBX.js';
|
|
5
6
|
import './chunk-IQKHRPJR.js';
|
|
6
7
|
import './chunk-ITLSDZHK.js';
|
|
7
8
|
import './chunk-QFA3K5ZV.js';
|
|
8
9
|
import './chunk-AIK7CDV6.js';
|
|
9
|
-
import { createContext,
|
|
10
|
+
import { createContext, forwardRef, useRef, useImperativeHandle, useEffect, useMemo, useContext } from 'react';
|
|
10
11
|
import { jsx } from 'react/jsx-runtime';
|
|
11
12
|
|
|
12
|
-
var ChecktivContext=createContext(null);function ChecktivProvider(props){if(typeof window==="undefined")return null;return jsx(ProviderImpl,{...props})}function ProviderImpl(props){const{getSessionToken,theme,locale,children}=props;const scope="publishableKey"in props?{publishableKey:props.publishableKey}:{region:props.region,mode:props.mode};const pk="publishableKey"in props?props.publishableKey:void 0;const region="publishableKey"in props?void 0:props.region;const mode="publishableKey"in props?void 0:props.mode;const themeKey=JSON.stringify(theme??null);const client=useMemo(()=>init({...scope,getSessionToken,theme,locale}),[pk,region,mode,getSessionToken,themeKey,locale]);return jsx(ChecktivContext.Provider,{value:client,children})}function useChecktiv(){const client=useContext(ChecktivContext);if(client===null){throw new Error("useChecktiv must be used within a <ChecktivProvider>. Wrap the component tree that needs the Checktiv client with <ChecktivProvider>.")}return client}function ChecktivIdv({onEvent,copy,layout,onBeforeSubmit,onBehaviorSegment}){const client=useChecktiv();const containerRef=useRef(null);const handleRef=useRef(null);const mountConfigRef=useRef({copy,layout,onBeforeSubmit,onBehaviorSegment});const onEventRef=useRef(onEvent);onEventRef.current=onEvent;useEffect(()=>{if(typeof window==="undefined")return;if(containerRef.current===null)return;if(handleRef.current!==null)return;const mountConfig=mountConfigRef.current;handleRef.current=client.mount("idv",{target:containerRef.current,onEvent:e=>onEventRef.current(e),...mountConfig.copy!==void 0?{copy:mountConfig.copy}:{},...mountConfig.layout!==void 0?{layout:mountConfig.layout}:{},...mountConfig.onBeforeSubmit!==void 0?{onBeforeSubmit:mountConfig.onBeforeSubmit}:{},...mountConfig.onBehaviorSegment!==void 0?{onBehaviorSegment:mountConfig.onBehaviorSegment}:{}});return ()=>{handleRef.current?.destroy();handleRef.current=null;}},[client]);if(typeof window==="undefined")return null;return jsx("div",{ref:containerRef})}
|
|
13
|
+
var ChecktivContext=createContext(null);function ChecktivProvider(props){if(typeof window==="undefined")return null;return jsx(ProviderImpl,{...props})}function ProviderImpl(props){const{getSessionToken,theme,locale,children}=props;const scope="publishableKey"in props?{publishableKey:props.publishableKey}:{region:props.region,mode:props.mode};const pk="publishableKey"in props?props.publishableKey:void 0;const region="publishableKey"in props?void 0:props.region;const mode="publishableKey"in props?void 0:props.mode;const themeKey=JSON.stringify(theme??null);const client=useMemo(()=>init({...scope,getSessionToken,theme,locale}),[pk,region,mode,getSessionToken,themeKey,locale]);return jsx(ChecktivContext.Provider,{value:client,children})}function useChecktiv(){const client=useContext(ChecktivContext);if(client===null){throw new Error("useChecktiv must be used within a <ChecktivProvider>. Wrap the component tree that needs the Checktiv client with <ChecktivProvider>.")}return client}function ChecktivIdv({onEvent,copy,layout,onBeforeSubmit,onBehaviorSegment}){const client=useChecktiv();const containerRef=useRef(null);const handleRef=useRef(null);const mountConfigRef=useRef({copy,layout,onBeforeSubmit,onBehaviorSegment});const onEventRef=useRef(onEvent);onEventRef.current=onEvent;useEffect(()=>{if(typeof window==="undefined")return;if(containerRef.current===null)return;if(handleRef.current!==null)return;const mountConfig=mountConfigRef.current;handleRef.current=client.mount("idv",{target:containerRef.current,onEvent:e=>onEventRef.current(e),...mountConfig.copy!==void 0?{copy:mountConfig.copy}:{},...mountConfig.layout!==void 0?{layout:mountConfig.layout}:{},...mountConfig.onBeforeSubmit!==void 0?{onBeforeSubmit:mountConfig.onBeforeSubmit}:{},...mountConfig.onBehaviorSegment!==void 0?{onBehaviorSegment:mountConfig.onBehaviorSegment}:{}});return ()=>{handleRef.current?.destroy();handleRef.current=null;}},[client]);if(typeof window==="undefined")return null;return jsx("div",{ref:containerRef})}var ChecktivJourneyImpl=(props,ref)=>{const containerRef=useRef(null);const handleRef=useRef(null);const scope="publishableKey"in props?{publishableKey:props.publishableKey}:{region:props.region,mode:props.mode};const pk="publishableKey"in props?props.publishableKey:void 0;const region="publishableKey"in props?void 0:props.region;const mode="publishableKey"in props?void 0:props.mode;const journeyConfig={fetchToken:props.fetchToken,onConsent:props.onConsent,layout:props.layout,theme:props.theme,resumeKey:props.resumeKey,shortCode:props.shortCode,apiBase:props.apiBase,fetchImpl:props.fetchImpl};const mountConfigRef=useRef(journeyConfig);mountConfigRef.current=journeyConfig;const onEventRef=useRef(props.onEvent);onEventRef.current=props.onEvent;const onCompleteRef=useRef(props.onComplete);onCompleteRef.current=props.onComplete;useImperativeHandle(ref,()=>({requestResend:confirmEmail=>handleRef.current?.requestResend(confirmEmail)??Promise.resolve({requested:false})}),[]);useEffect(()=>{if(typeof window==="undefined")return;if(containerRef.current===null)return;if(handleRef.current!==null)return;const cfg=mountConfigRef.current;const opts={...scope,fetchToken:cfg.fetchToken,onEvent:e=>onEventRef.current?.(e),onComplete:r=>onCompleteRef.current?.(r),...cfg.onConsent!==void 0?{onConsent:cfg.onConsent}:{},...cfg.layout!==void 0?{layout:cfg.layout}:{},...cfg.theme!==void 0?{theme:cfg.theme}:{},...cfg.resumeKey!==void 0?{resumeKey:cfg.resumeKey}:{},...cfg.shortCode!==void 0?{shortCode:cfg.shortCode}:{},...cfg.apiBase!==void 0?{apiBase:cfg.apiBase}:{},...cfg.fetchImpl!==void 0?{fetchImpl:cfg.fetchImpl}:{}};handleRef.current=mount(containerRef.current,opts);return ()=>{handleRef.current?.destroy();handleRef.current=null;}},[pk,region,mode]);if(typeof window==="undefined")return null;return jsx("div",{ref:containerRef})};var ChecktivJourney=forwardRef(ChecktivJourneyImpl);
|
|
13
14
|
|
|
14
|
-
export { ChecktivIdv, ChecktivProvider, useChecktiv };
|
|
15
|
+
export { ChecktivIdv, ChecktivJourney, ChecktivProvider, useChecktiv };
|
package/dist/workspace.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checktiv/sdk-web",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"//publishConfigNameNote": "pnpm does NOT apply `publishConfig.name` (the publishConfig override list at https://pnpm.io/package_json#publishconfig excludes `name`; `pnpm pack` leaves the tarball `name` as the workspace name). The published `name` rewrite to `@checktiv/sdk-web` happens in the root `.pnpmfile.cjs` `beforePacking` hook (pnpm >= 10.28) instead — see that file's header. This field is retained ONLY as documentation of intent; the hook deletes it from the packed manifest. The packed-name gate in __tests__/dist-shape.test.ts reads the REAL extracted tarball, not this field.",
|
|
@@ -114,8 +114,8 @@
|
|
|
114
114
|
"vitest": "^4.1.9",
|
|
115
115
|
"@rf/iam-core": "0.0.1",
|
|
116
116
|
"@rf/schemas": "0.1.0",
|
|
117
|
-
"@rf/
|
|
118
|
-
"@rf/
|
|
117
|
+
"@rf/config": "0.0.0",
|
|
118
|
+
"@rf/theme": "0.1.0"
|
|
119
119
|
},
|
|
120
120
|
"scripts": {
|
|
121
121
|
"build": "tsup && node scripts/generate-agent-steering.mjs && pnpm run build:embed-capture && pnpm run build:embed-challenge && pnpm run build:host-capture && pnpm run build:cross-device",
|
package/dist/chunk-BEZGAQ74.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { getModule } from './chunk-GFHNOZVO.js';
|
|
2
|
-
import { assertNever } from './chunk-UBQTPS5J.js';
|
|
3
|
-
import { createTokenManager, resolveSession, warnWrongTokenPlane, createChecktivError } from './chunk-QVDWM4KK.js';
|
|
4
|
-
import { resolveApiBaseOrigin } from './chunk-ITLSDZHK.js';
|
|
5
|
-
|
|
6
|
-
var PUBLISHABLE_KEY_REGEX=/^ah_pk_(us|eu)_(live|test)_[A-Za-z0-9_-]{8,}$/;var InvalidPublishableKeyError=class extends Error{constructor(message){super(message);this.name="InvalidPublishableKeyError";}};function parsePublishableKey(key){const match=PUBLISHABLE_KEY_REGEX.exec(key);if(!match){throw new InvalidPublishableKeyError(`Invalid publishable key format. Expected ah_pk_<us|eu>_<live|test>_<token>, got: ${maskKey(key)}`)}const region=match[1];const mode=match[2];if(region!=="us"&®ion!=="eu"){throw new InvalidPublishableKeyError(`Invalid region in publishable key: ${maskKey(key)}`)}if(mode!=="test"&&mode!=="live"){throw new InvalidPublishableKeyError(`Invalid mode in publishable key: ${maskKey(key)}`)}return {region,mode}}function maskKey(key){if(key.length<=8)return "***";return `${key.slice(0,6)}...${key.slice(-2)}`}function moduleErrorEvent(name,error){switch(name){case "idv":return {type:"checktiv.idv.error",error};case "fraud":return {type:"checktiv.fraud.error",error};case "custom_form":return {type:"checktiv.custom_form.error",error}}}function missingModuleMessage(name){return `This session requires the '${name}' module. Import '@checktiv/sdk-web/${name}' in your app.`}function missingModuleError(name){const base=createChecktivError("sdk_load_failed");return moduleErrorEvent(name,{...base,message:missingModuleMessage(name)})}function consentGateRequiredError(){const base=createChecktivError("sdk_load_failed");return moduleErrorEvent("fraud",{...base,message:"This session includes the 'fraud' module, which needs a consent gate. Pass onConsent to mountProvisioned() to enable it."})}function customFormConfigRequiredError(){const base=createChecktivError("sdk_load_failed");return moduleErrorEvent("custom_form",{...base,message:"This session includes the 'custom_form' module, which needs its form config. Pass customFormConfig to mountProvisioned() to enable it."})}function unmappedStepTypeError(stepType){const base=createChecktivError("sdk_load_failed");return moduleErrorEvent("idv",{...base,message:`This session's current step ('${stepType}') has no matching visual module in this SDK build. Upgrade '@checktiv/sdk-web' to a version that renders this step.`})}var MODULE_IS_VISUAL={idv:true,fraud:false,custom_form:true};var STEP_TYPE_TO_VISUAL_MODULE={id_verification:"idv",custom_form:"custom_form"};var stepTypeToVisualModuleView=STEP_TYPE_TO_VISUAL_MODULE;function resolveCurrentStepVisualModule(stepType){return stepTypeToVisualModuleView[stepType]}function defaultLoadModule(name){if(name==="idv"){const factory2=getModule("idv");if(factory2===void 0)return Promise.resolve(null);return Promise.resolve({mount:(ctx,opts)=>factory2(ctx,{target:opts.target,onEvent:opts.onEvent,copy:opts.copy,layout:opts.layout,onBeforeSubmit:opts.onBeforeSubmit,onBehaviorSegment:opts.onBehaviorSegment,synthetic:opts.synthetic})})}if(name==="custom_form"){const factory2=getModule("custom_form");if(factory2===void 0)return Promise.resolve(null);return Promise.resolve({mount:(ctx,opts)=>{if(opts.customFormConfig===void 0){opts.onEvent?.(customFormConfigRequiredError());return {destroy:()=>void 0}}return factory2(ctx,{target:opts.target,config:opts.customFormConfig,copy:opts.customFormCopy,onEvent:opts.onEvent,session:opts.session})}})}const factory=getModule("fraud");if(factory===void 0)return Promise.resolve(null);return Promise.resolve({mount:(ctx,opts)=>{const onConsent=opts.onConsent;if(onConsent===void 0){opts.onEvent?.(consentGateRequiredError());return {destroy:()=>void 0}}return factory(ctx,{onConsent,onEvent:opts.onEvent})}})}function moduleErrorFor(name,code){return moduleErrorEvent(name,createChecktivError(code))}function createMountProvisioned(ctx,opts,deps={}){const emit=e=>opts.onEvent?.(e);const fetchImpl=opts.fetchImpl??fetch;const resolveSession2=deps.resolveSession??(()=>resolveSession(ctx,fetchImpl));const loadModule=deps.loadModule??defaultLoadModule;const handles=[];let destroyed=false;void(async()=>{try{await composeModules();}catch(err){if(destroyed)return;console.warn("[Checktiv] mountProvisioned composition failed.",err);emit(moduleErrorFor("idv","sdk_load_failed"));}})();async function composeModules(){const resolution=await resolveSession2();if(destroyed)return;let session;switch(resolution.kind){case "ok":session=resolution.session;break;case "wrong_token":warnWrongTokenPlane();emit(moduleErrorFor("idv","wrong_token_type"));return;case "unresolved":emit(moduleErrorFor("idv","session_expired"));return;default:return assertNever(resolution)}const currentStepVisualModule=resolveCurrentStepVisualModule(session.stepType);if(currentStepVisualModule===void 0&&session.modules.some(m=>MODULE_IS_VISUAL[m])){emit(unmappedStepTypeError(session.stepType));return}for(const name of session.modules){if(destroyed)return;if(MODULE_IS_VISUAL[name]&&name!==currentStepVisualModule){continue}if(name==="fraud"&&opts.onConsent===void 0){emit(consentGateRequiredError());continue}const mod=await loadModule(name);if(destroyed)return;if(mod===null){emit(missingModuleError(name));continue}let moduleTarget;let containerToRemove=null;if(MODULE_IS_VISUAL[name]){const resolvedParent=typeof opts.target==="string"?typeof document!=="undefined"?document.querySelector(opts.target):null:opts.target;if(resolvedParent!==null){const container=document.createElement("div");resolvedParent.appendChild(container);containerToRemove=container;moduleTarget=container;}else {moduleTarget=opts.target;}}else {moduleTarget=opts.target;}let innerHandle;try{innerHandle=mod.mount(ctx,{target:moduleTarget,onEvent:opts.onEvent,onConsent:opts.onConsent,copy:opts.copy,layout:opts.layout,onBeforeSubmit:opts.onBeforeSubmit,onBehaviorSegment:opts.onBehaviorSegment,synthetic:opts.synthetic,customFormConfig:opts.customFormConfig,customFormCopy:opts.customFormCopy,session:{sessionId:session.sessionId,stepId:session.stepId}});}catch(err){containerToRemove?.remove();throw err}const capturedContainer=containerToRemove;const handle={destroy(){try{innerHandle.destroy();}finally{capturedContainer?.remove();}}};if(destroyed){handle.destroy();return}handles.push(handle);}}return {destroy(){destroyed=true;while(handles.length>0){const handle=handles.pop();handle?.destroy();}}}}function init(opts,deps={}){const scope="publishableKey"in opts?{...parsePublishableKey(opts.publishableKey),publishableKey:opts.publishableKey}:{region:opts.region,mode:opts.mode,publishableKey:void 0};let sessionId="";const apiBaseOrigin=resolveApiBaseOrigin(opts.apiBase,scope.region,scope.mode);const ctx={region:scope.region,mode:scope.mode,publishableKey:scope.publishableKey,apiBaseOrigin,theme:opts.theme,locale:opts.locale??"en",betas:opts.betas??[],...opts.selfiePromptMap!==void 0?{selfiePromptMap:opts.selfiePromptMap}:{},...opts.selfieChromeCopy!==void 0?{selfieChromeCopy:opts.selfieChromeCopy}:{},tokens:deps.tokens??createTokenManager(opts.getSessionToken,()=>sessionId),getSessionId:()=>sessionId,setSessionId:id=>{sessionId=id;}};function mount(...args){if(args[0]==="idv"){const factory2=getModule("idv");if(factory2===void 0)return missingIdvHandle(args[1]);return factory2(ctx,args[1])}if(args[0]==="custom_form"){const factory2=getModule("custom_form");if(factory2===void 0)return missingCustomFormHandle(args[1]);return factory2(ctx,args[1])}const factory=getModule("fraud");if(factory===void 0)return missingFraudHandle(args[1]);return factory(ctx,args[1])}return {mountProvisioned:provOpts=>createMountProvisioned(ctx,provOpts),mount}}function missingIdvHandle(opts){const base=createChecktivError("sdk_load_failed");opts.onEvent?.({type:"checktiv.idv.error",error:{...base,message:missingModuleMessage("idv")}});return {destroy:()=>void 0,unmount:()=>void 0}}function missingFraudHandle(opts){const base=createChecktivError("sdk_load_failed");opts.onEvent?.({type:"checktiv.fraud.error",error:{...base,message:missingModuleMessage("fraud")}});return {destroy:()=>void 0}}function missingCustomFormHandle(opts){const base=createChecktivError("sdk_load_failed");const error={type:"checktiv.custom_form.error",error:{...base,message:missingModuleMessage("custom_form")}};opts.onEvent?.(error);return {destroy:()=>void 0}}
|
|
7
|
-
|
|
8
|
-
export { InvalidPublishableKeyError, init, parsePublishableKey };
|