@metamask-previews/kyc-controller 0.0.0-preview-abca9bcea → 0.0.0-preview-8bfa290fb
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/CHANGELOG.md +0 -6
- package/dist/KycController-method-action-types.cjs.map +1 -1
- package/dist/KycController-method-action-types.d.cts +4 -6
- package/dist/KycController-method-action-types.d.cts.map +1 -1
- package/dist/KycController-method-action-types.d.mts +4 -6
- package/dist/KycController-method-action-types.d.mts.map +1 -1
- package/dist/KycController-method-action-types.mjs.map +1 -1
- package/dist/KycController.cjs +302 -179
- package/dist/KycController.cjs.map +1 -1
- package/dist/KycController.d.cts +37 -43
- package/dist/KycController.d.cts.map +1 -1
- package/dist/KycController.d.mts +37 -43
- package/dist/KycController.d.mts.map +1 -1
- package/dist/KycController.mjs +301 -176
- package/dist/KycController.mjs.map +1 -1
- package/dist/KycService-method-action-types.cjs.map +1 -1
- package/dist/KycService-method-action-types.d.cts +4 -4
- package/dist/KycService-method-action-types.d.mts +4 -4
- package/dist/KycService-method-action-types.mjs.map +1 -1
- package/dist/KycService.cjs +13 -21
- package/dist/KycService.cjs.map +1 -1
- package/dist/KycService.d.cts +4 -4
- package/dist/KycService.d.cts.map +1 -1
- package/dist/KycService.d.mts +4 -4
- package/dist/KycService.d.mts.map +1 -1
- package/dist/KycService.mjs +13 -21
- package/dist/KycService.mjs.map +1 -1
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +11 -50
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +11 -50
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/vendorDisclaimerAcceptance.cjs +0 -74
- package/dist/vendorDisclaimerAcceptance.cjs.map +0 -1
- package/dist/vendorDisclaimerAcceptance.d.cts +0 -39
- package/dist/vendorDisclaimerAcceptance.d.cts.map +0 -1
- package/dist/vendorDisclaimerAcceptance.d.mts +0 -39
- package/dist/vendorDisclaimerAcceptance.d.mts.map +0 -1
- package/dist/vendorDisclaimerAcceptance.mjs +0 -67
- package/dist/vendorDisclaimerAcceptance.mjs.map +0 -1
- package/dist/vendors/MoonPayFrameHandler.cjs +0 -235
- package/dist/vendors/MoonPayFrameHandler.cjs.map +0 -1
- package/dist/vendors/MoonPayFrameHandler.d.cts +0 -74
- package/dist/vendors/MoonPayFrameHandler.d.cts.map +0 -1
- package/dist/vendors/MoonPayFrameHandler.d.mts +0 -74
- package/dist/vendors/MoonPayFrameHandler.d.mts.map +0 -1
- package/dist/vendors/MoonPayFrameHandler.mjs +0 -230
- package/dist/vendors/MoonPayFrameHandler.mjs.map +0 -1
package/dist/KycController.mjs
CHANGED
|
@@ -9,10 +9,11 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _KycController_instances, _KycController_sumsubLauncher,
|
|
12
|
+
var _KycController_instances, _KycController_sumsubLauncher, _KycController_moonpayFrameKeypair, _KycController_authClientToken, _KycController_generation, _KycController_sessionStatusPollIntervalMs, _KycController_pollTimer, _KycController_pollToken, _KycController_userStatusPollIntervalMs, _KycController_userStatusPollTimer, _KycController_userStatusPolling, _KycController_userStatusPollToken, _KycController_localUserSecretStore, _KycController_startConsentsSession, _KycController_recordSessionDisclaimers, _KycController_createSession, _KycController_clearAcceptedTerms, _KycController_clearMoonPaySession, _KycController_dropTermsUnlessForVendor, _KycController_hasTermsForVendor, _KycController_handleCheckOutcome, _KycController_handleAuthOutcome, _KycController_continueAfterAuthentication, _KycController_requireTermsReacceptance, _KycController_buildUkycSessionVendorFields, _KycController_createUkycSession, _KycController_fetchAndApplyUserStatus, _KycController_applyUserStatus, _KycController_ensureUserStatusPolling, _KycController_stopUserStatusPolling, _KycController_startSessionStatusPolling, _KycController_pollSessionStatusOnce, _KycController_stopPolling, _KycController_cancelPendingSession, _KycController_updateIfCurrent, _KycController_applyUpdate, _KycController_assertAttestedServerPublicKey, _KycController_fail;
|
|
13
13
|
import { BaseController } from "@metamask/base-controller";
|
|
14
14
|
import { stringToBytes } from "@metamask/utils";
|
|
15
15
|
import { x25519 } from "@noble/curves/ed25519";
|
|
16
|
+
import { decryptCredentials, generateKeyPair } from "./crypto.mjs";
|
|
16
17
|
import { toBase64Url } from "./encoding.mjs";
|
|
17
18
|
import { controllerLog } from "./logger.mjs";
|
|
18
19
|
import { deriveClientMaterial } from "./ukyc/deriveClientMaterial.mjs";
|
|
@@ -20,10 +21,12 @@ import { verifyJwtChain } from "./ukyc/jwtChain.mjs";
|
|
|
20
21
|
import { getOrCreateLocalUserSecret } from "./ukyc/localUserSecret.mjs";
|
|
21
22
|
import { encodeStorageAccessTokenForHeader, signStorageAccessToken } from "./ukyc/storageAccessToken.mjs";
|
|
22
23
|
import { wrapEncryptionKey } from "./ukyc/wrapEncryptionKey.mjs";
|
|
23
|
-
import { clearVendorDisclaimerAcceptance, hasVendorDisclaimerAcceptance, ironDisclaimerIds, recordVendorDisclaimerAcceptance } from "./vendorDisclaimerAcceptance.mjs";
|
|
24
|
-
import { clearMoonPaySession, MoonPayFrameHandler } from "./vendors/MoonPayFrameHandler.mjs";
|
|
25
24
|
// === GENERAL ===
|
|
26
25
|
export const controllerName = 'KycController';
|
|
26
|
+
const FRAMES_BASE_URL = 'https://blocks.moonpay.com/platform/v1';
|
|
27
|
+
const CHANNEL_CHECK = 'ch_1';
|
|
28
|
+
const CHANNEL_AUTH = 'ch_2';
|
|
29
|
+
const CHANNEL_RESET = 'ch_reset';
|
|
27
30
|
// Placeholder credentials for the SumSub sub-flow. These are demo values that
|
|
28
31
|
// must be replaced with real UKYC-issued material before production use.
|
|
29
32
|
const MOCK_JWT_TOKEN = 'mock-jwt-token';
|
|
@@ -114,19 +117,31 @@ const kycControllerMetadata = {
|
|
|
114
117
|
persist: false,
|
|
115
118
|
usedInUi: false,
|
|
116
119
|
},
|
|
117
|
-
|
|
120
|
+
termsAcceptedAt: {
|
|
118
121
|
includeInDebugSnapshot: true,
|
|
119
122
|
includeInStateLogs: true,
|
|
120
123
|
persist: true,
|
|
121
124
|
usedInUi: false,
|
|
122
125
|
},
|
|
123
|
-
|
|
126
|
+
acceptedDisclaimerIds: {
|
|
124
127
|
includeInDebugSnapshot: true,
|
|
125
128
|
includeInStateLogs: true,
|
|
126
129
|
persist: true,
|
|
127
130
|
usedInUi: false,
|
|
128
131
|
},
|
|
129
|
-
|
|
132
|
+
termsAcceptedVendor: {
|
|
133
|
+
includeInDebugSnapshot: true,
|
|
134
|
+
includeInStateLogs: true,
|
|
135
|
+
persist: true,
|
|
136
|
+
usedInUi: false,
|
|
137
|
+
},
|
|
138
|
+
sumsubTncAccepted: {
|
|
139
|
+
includeInDebugSnapshot: true,
|
|
140
|
+
includeInStateLogs: true,
|
|
141
|
+
persist: true,
|
|
142
|
+
usedInUi: false,
|
|
143
|
+
},
|
|
144
|
+
idosTncAccepted: {
|
|
130
145
|
includeInDebugSnapshot: true,
|
|
131
146
|
includeInStateLogs: true,
|
|
132
147
|
persist: true,
|
|
@@ -138,13 +153,13 @@ const kycControllerMetadata = {
|
|
|
138
153
|
persist: false,
|
|
139
154
|
usedInUi: false,
|
|
140
155
|
},
|
|
141
|
-
|
|
156
|
+
disclaimers: {
|
|
142
157
|
includeInDebugSnapshot: false,
|
|
143
158
|
includeInStateLogs: false,
|
|
144
159
|
persist: false,
|
|
145
160
|
usedInUi: true,
|
|
146
161
|
},
|
|
147
|
-
|
|
162
|
+
disclaimersError: {
|
|
148
163
|
includeInDebugSnapshot: true,
|
|
149
164
|
includeInStateLogs: true,
|
|
150
165
|
persist: false,
|
|
@@ -162,13 +177,13 @@ const kycControllerMetadata = {
|
|
|
162
177
|
persist: false,
|
|
163
178
|
usedInUi: true,
|
|
164
179
|
},
|
|
165
|
-
|
|
180
|
+
sessionToken: {
|
|
166
181
|
includeInDebugSnapshot: false,
|
|
167
182
|
includeInStateLogs: false,
|
|
168
183
|
persist: false,
|
|
169
184
|
usedInUi: false,
|
|
170
185
|
},
|
|
171
|
-
|
|
186
|
+
accessToken: {
|
|
172
187
|
includeInDebugSnapshot: false,
|
|
173
188
|
includeInStateLogs: false,
|
|
174
189
|
persist: false,
|
|
@@ -229,17 +244,6 @@ const kycControllerMetadata = {
|
|
|
229
244
|
usedInUi: true,
|
|
230
245
|
},
|
|
231
246
|
};
|
|
232
|
-
/**
|
|
233
|
-
* Constructs the default {@link KycVendorDisclaimersAccepted} value.
|
|
234
|
-
*
|
|
235
|
-
* @returns The default vendor-disclaimer acceptance map.
|
|
236
|
-
*/
|
|
237
|
-
export function getDefaultKycVendorDisclaimersAccepted() {
|
|
238
|
-
return { moonpay: null, iron: null };
|
|
239
|
-
}
|
|
240
|
-
export function getDefaultKycProviderDisclaimersAccepted() {
|
|
241
|
-
return { sumsub: null };
|
|
242
|
-
}
|
|
243
247
|
/**
|
|
244
248
|
* Constructs the default {@link KycController} state.
|
|
245
249
|
*
|
|
@@ -251,16 +255,18 @@ export function getDefaultKycControllerState() {
|
|
|
251
255
|
statusMessage: '',
|
|
252
256
|
error: null,
|
|
253
257
|
email: null,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
258
|
+
termsAcceptedAt: null,
|
|
259
|
+
acceptedDisclaimerIds: [],
|
|
260
|
+
termsAcceptedVendor: null,
|
|
261
|
+
sumsubTncAccepted: null,
|
|
262
|
+
idosTncAccepted: null,
|
|
257
263
|
credentialReusabilityConsentGiven: null,
|
|
258
|
-
|
|
259
|
-
|
|
264
|
+
disclaimers: [],
|
|
265
|
+
disclaimersError: null,
|
|
260
266
|
sessionDisclaimers: null,
|
|
261
267
|
geoCountry: null,
|
|
262
|
-
|
|
263
|
-
|
|
268
|
+
sessionToken: null,
|
|
269
|
+
accessToken: null,
|
|
264
270
|
moonpayCustomerId: null,
|
|
265
271
|
activeVendor: 'moonpay',
|
|
266
272
|
activeProduct: null,
|
|
@@ -304,62 +310,45 @@ function isConsentConflictError(error) {
|
|
|
304
310
|
error.httpStatus === 409);
|
|
305
311
|
}
|
|
306
312
|
/**
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
*/
|
|
311
|
-
function isValidConsentRecordList(value) {
|
|
312
|
-
return (Array.isArray(value) &&
|
|
313
|
-
value.every((item) => typeof item === 'object' &&
|
|
314
|
-
item !== null &&
|
|
315
|
-
typeof item.key === 'string' &&
|
|
316
|
-
typeof item.version === 'string'));
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Maps accepted disclaimer records onto unconsented catalog documents.
|
|
313
|
+
* Maps a session-disclaimer catalog into the `{ key, version }` records the
|
|
314
|
+
* record-consents API expects, or an empty list when the user declined that
|
|
315
|
+
* category.
|
|
320
316
|
*
|
|
321
317
|
* @param documents - Catalog documents for one consent category.
|
|
322
|
-
* @param accepted -
|
|
323
|
-
* @returns Consent records
|
|
318
|
+
* @param accepted - Whether the user accepted that category.
|
|
319
|
+
* @returns Consent records, or `[]` when not accepted.
|
|
324
320
|
*/
|
|
325
|
-
function
|
|
326
|
-
if (accepted
|
|
321
|
+
function consentRecordsFromCatalog(documents, accepted) {
|
|
322
|
+
if (!accepted) {
|
|
327
323
|
return [];
|
|
328
324
|
}
|
|
329
|
-
const acceptedKeys = new Set(accepted.map((record) => `${record.key}:${record.version}`));
|
|
330
325
|
return documents
|
|
331
|
-
.filter((document) => !document.consented
|
|
332
|
-
acceptedKeys.has(`${document.key}:${document.version}`))
|
|
326
|
+
.filter((document) => !document.consented)
|
|
333
327
|
.map(({ key, version }) => ({ key, version }));
|
|
334
328
|
}
|
|
335
329
|
/**
|
|
336
|
-
* Whether accepted
|
|
330
|
+
* Whether an accepted T&C2 category has no catalog documents. An empty list
|
|
331
|
+
* would otherwise skip the POST and count as success.
|
|
337
332
|
*
|
|
338
333
|
* @param documents - Catalog documents for one consent category.
|
|
339
|
-
* @param accepted -
|
|
340
|
-
* @returns `true` when the
|
|
334
|
+
* @param accepted - Whether the user accepted that category.
|
|
335
|
+
* @returns `true` when the user accepted and the catalog is empty.
|
|
341
336
|
*/
|
|
342
337
|
function isAcceptedCategoryEmpty(documents, accepted) {
|
|
343
|
-
return accepted
|
|
338
|
+
return accepted && documents.length === 0;
|
|
344
339
|
}
|
|
345
340
|
/**
|
|
346
|
-
* Whether accepted
|
|
347
|
-
* empty catalog or any
|
|
341
|
+
* Whether an accepted category is still missing consent after a 409 re-GET:
|
|
342
|
+
* empty catalog or any document still unconsented.
|
|
348
343
|
*
|
|
349
344
|
* @param documents - Latest catalog documents for one consent category.
|
|
350
|
-
* @param accepted -
|
|
345
|
+
* @param accepted - Whether the user accepted that category.
|
|
351
346
|
* @returns `true` when accepted documents are not fully consented.
|
|
352
347
|
*/
|
|
353
348
|
function acceptedCategoryStillMissing(documents, accepted) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
if (documents.length === 0) {
|
|
358
|
-
return true;
|
|
359
|
-
}
|
|
360
|
-
const acceptedKeys = new Set(accepted.map((record) => `${record.key}:${record.version}`));
|
|
361
|
-
const relevant = documents.filter((document) => acceptedKeys.has(`${document.key}:${document.version}`));
|
|
362
|
-
return (relevant.length === 0 || relevant.some((document) => !document.consented));
|
|
349
|
+
return (accepted &&
|
|
350
|
+
(documents.length === 0 ||
|
|
351
|
+
documents.some((document) => !document.consented)));
|
|
363
352
|
}
|
|
364
353
|
/**
|
|
365
354
|
* Vendors other than MoonPay skip Check/Auth frames and use the empty-shell
|
|
@@ -395,9 +384,9 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
395
384
|
/**
|
|
396
385
|
* `KycController` orchestrates the vendor-backed KYC / identity-verification
|
|
397
386
|
* flow (MoonPay identity + SumSub documents) behind a vendor-neutral, per
|
|
398
|
-
* product surface used by ramps and card. It owns all state
|
|
399
|
-
* orchestration (via `KycService`),
|
|
400
|
-
* platform-specific presentation (WebView/iframe, SumSub SDK)
|
|
387
|
+
* product surface used by ramps and card. It owns all state, HTTP
|
|
388
|
+
* orchestration (via `KycService`), crypto, and the frame message protocol;
|
|
389
|
+
* platform-specific presentation (WebView/iframe, SumSub SDK) is injected.
|
|
401
390
|
*/
|
|
402
391
|
export class KycController extends BaseController {
|
|
403
392
|
/**
|
|
@@ -421,8 +410,10 @@ export class KycController extends BaseController {
|
|
|
421
410
|
});
|
|
422
411
|
_KycController_instances.add(this);
|
|
423
412
|
_KycController_sumsubLauncher.set(this, void 0);
|
|
424
|
-
/** MoonPay
|
|
425
|
-
|
|
413
|
+
/** MoonPay Check/Auth frame X25519 keypair (never persisted). */
|
|
414
|
+
_KycController_moonpayFrameKeypair.set(this, null);
|
|
415
|
+
/** Auth-frame client token, kept out of state. */
|
|
416
|
+
_KycController_authClientToken.set(this, null);
|
|
426
417
|
/**
|
|
427
418
|
* Monotonic flow generation. Incremented by {@link reset} and
|
|
428
419
|
* {@link clearState} so in-flight async work (e.g. the KYC-required check)
|
|
@@ -459,13 +450,6 @@ export class KycController extends BaseController {
|
|
|
459
450
|
__classPrivateFieldSet(this, _KycController_sumsubLauncher, sumsubLauncher, "f");
|
|
460
451
|
__classPrivateFieldSet(this, _KycController_sessionStatusPollIntervalMs, sessionStatusPollIntervalMs, "f");
|
|
461
452
|
__classPrivateFieldSet(this, _KycController_userStatusPollIntervalMs, userStatusPollIntervalMs, "f");
|
|
462
|
-
__classPrivateFieldSet(this, _KycController_moonPayFrames, new MoonPayFrameHandler({
|
|
463
|
-
getState: () => this.state,
|
|
464
|
-
update: (updater) => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, updater),
|
|
465
|
-
fail: (message) => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, message),
|
|
466
|
-
onAuthenticated: async () => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this),
|
|
467
|
-
requireTermsReacceptance: () => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this),
|
|
468
|
-
}), "f");
|
|
469
453
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
470
454
|
}
|
|
471
455
|
/**
|
|
@@ -490,16 +474,16 @@ export class KycController extends BaseController {
|
|
|
490
474
|
// consumer drive it (or call `reset` first to start over).
|
|
491
475
|
const vendor = params?.vendor ?? 'moonpay';
|
|
492
476
|
if (IN_PROGRESS_PHASES.includes(this.state.phase)) {
|
|
493
|
-
if (vendor === 'moonpay') {
|
|
494
|
-
|
|
477
|
+
if (vendor === 'moonpay' && !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
|
|
478
|
+
__classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, generateKeyPair(), "f");
|
|
495
479
|
}
|
|
496
480
|
return;
|
|
497
481
|
}
|
|
498
482
|
if (vendor === 'moonpay') {
|
|
499
|
-
|
|
483
|
+
__classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, generateKeyPair(), "f");
|
|
500
484
|
}
|
|
501
485
|
else {
|
|
502
|
-
|
|
486
|
+
__classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, null, "f");
|
|
503
487
|
}
|
|
504
488
|
// `initialize` starts a fresh flow, so `activeProduct` is always reset to
|
|
505
489
|
// this call's product (or `null`). Otherwise a prior run's product could
|
|
@@ -510,9 +494,14 @@ export class KycController extends BaseController {
|
|
|
510
494
|
state.email = params.email;
|
|
511
495
|
}
|
|
512
496
|
state.activeVendor = vendor;
|
|
513
|
-
// MoonPay Check/Auth artifacts must not survive a switch to another
|
|
497
|
+
// MoonPay Check/Auth artifacts must not survive a switch to another
|
|
498
|
+
// vendor: leftover `sessionToken` would keep `buildCheckFrameUrl` alive,
|
|
499
|
+
// leftover `accessToken` / `#authClientToken` would keep Auth / KYC
|
|
500
|
+
// calls bound to MoonPay, and leftover `moonpayCustomerId` would make
|
|
501
|
+
// `getCustomerIdentity` report a MoonPay id under the wrong vendor.
|
|
514
502
|
if (vendor !== 'moonpay') {
|
|
515
|
-
|
|
503
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
|
|
504
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
|
|
516
505
|
}
|
|
517
506
|
state.activeProduct = params?.product ?? null;
|
|
518
507
|
});
|
|
@@ -560,14 +549,16 @@ export class KycController extends BaseController {
|
|
|
560
549
|
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
561
550
|
return;
|
|
562
551
|
}
|
|
563
|
-
|
|
552
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_dropTermsUnlessForVendor).call(this, vendor);
|
|
553
|
+
const hasTerms = Boolean(this.state.termsAcceptedAt) &&
|
|
554
|
+
this.state.acceptedDisclaimerIds.length > 0;
|
|
564
555
|
if (hasTerms && this.state.email) {
|
|
565
556
|
if (usesConsentsFlow(vendor)) {
|
|
566
557
|
// Consents-path vendors require T&C2 flags; if they weren't persisted
|
|
567
558
|
// (i.e. null from pre-migration state), require reacceptance.
|
|
568
|
-
const
|
|
569
|
-
|
|
570
|
-
|
|
559
|
+
const sumsubTncSigned = this.state.sumsubTncAccepted;
|
|
560
|
+
const idosTncSigned = this.state.idosTncAccepted;
|
|
561
|
+
if (sumsubTncSigned === null || idosTncSigned === null) {
|
|
571
562
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
572
563
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
|
|
573
564
|
state.phase = 'terms';
|
|
@@ -576,19 +567,12 @@ export class KycController extends BaseController {
|
|
|
576
567
|
return;
|
|
577
568
|
}
|
|
578
569
|
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, {
|
|
579
|
-
|
|
580
|
-
|
|
570
|
+
sumsubTncSigned,
|
|
571
|
+
idosTncSigned,
|
|
581
572
|
credentialReusabilityConsentGiven: this.state.credentialReusabilityConsentGiven ?? false,
|
|
582
573
|
});
|
|
583
574
|
}
|
|
584
575
|
else {
|
|
585
|
-
// TODO: should this be here? or should it exist at all?
|
|
586
|
-
if (vendor === 'moonpay' && this.state.vendorDisclaimers.length === 0) {
|
|
587
|
-
await this.loadDisclaimers();
|
|
588
|
-
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
589
|
-
return;
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
576
|
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_createSession).call(this);
|
|
593
577
|
}
|
|
594
578
|
return;
|
|
@@ -622,8 +606,9 @@ export class KycController extends BaseController {
|
|
|
622
606
|
// after this request succeeds.
|
|
623
607
|
state.activeVendor = params.vendor;
|
|
624
608
|
if (params.vendor !== 'moonpay') {
|
|
625
|
-
|
|
626
|
-
|
|
609
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
|
|
610
|
+
__classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, null, "f");
|
|
611
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
|
|
627
612
|
}
|
|
628
613
|
});
|
|
629
614
|
const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
|
|
@@ -632,6 +617,10 @@ export class KycController extends BaseController {
|
|
|
632
617
|
vendor: params.vendor,
|
|
633
618
|
email: params.email,
|
|
634
619
|
});
|
|
620
|
+
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_dropTermsUnlessForVendor).call(this, params.vendor);
|
|
635
624
|
}
|
|
636
625
|
catch (error) {
|
|
637
626
|
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
@@ -665,13 +654,13 @@ export class KycController extends BaseController {
|
|
|
665
654
|
country,
|
|
666
655
|
});
|
|
667
656
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
668
|
-
state.
|
|
669
|
-
state.
|
|
657
|
+
state.disclaimers = disclaimers;
|
|
658
|
+
state.disclaimersError = null;
|
|
670
659
|
});
|
|
671
660
|
}
|
|
672
661
|
catch (error) {
|
|
673
662
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
674
|
-
state.
|
|
663
|
+
state.disclaimersError = `Failed to load disclaimers: ${String(error)}`;
|
|
675
664
|
});
|
|
676
665
|
}
|
|
677
666
|
}
|
|
@@ -684,47 +673,44 @@ export class KycController extends BaseController {
|
|
|
684
673
|
* @param params.product - The consuming feature the flow runs for. See
|
|
685
674
|
* {@link initialize} for how the product drives the automatic post
|
|
686
675
|
* authentication continuation.
|
|
687
|
-
* @param params.
|
|
688
|
-
*
|
|
689
|
-
*
|
|
690
|
-
*
|
|
691
|
-
* customer accepted (`{ key, version }` records). Required for every vendor
|
|
692
|
-
* so callers explicitly declare acceptance.
|
|
676
|
+
* @param params.sumsubTncSigned - Whether Sumsub T&C were accepted (T&C2).
|
|
677
|
+
* Required for every vendor so callers explicitly declare acceptance.
|
|
678
|
+
* @param params.idosTncSigned - Whether idOS T&C were accepted (T&C2).
|
|
679
|
+
* Required for every vendor so callers explicitly declare acceptance.
|
|
693
680
|
* @param params.credentialReusabilityConsentGiven - Whether the customer
|
|
694
681
|
* consented to reuse existing idOS credentials. Used when recording
|
|
695
682
|
* session-scoped disclaimers on the consents path. Defaults to `false`.
|
|
696
683
|
*/
|
|
697
684
|
async acceptTermsAndStartSession(params) {
|
|
698
|
-
const
|
|
699
|
-
const
|
|
700
|
-
if (
|
|
701
|
-
|
|
685
|
+
const sumsubTncSigned = params?.sumsubTncSigned;
|
|
686
|
+
const idosTncSigned = params?.idosTncSigned;
|
|
687
|
+
if (typeof sumsubTncSigned !== 'boolean' ||
|
|
688
|
+
typeof idosTncSigned !== 'boolean') {
|
|
702
689
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing T&C2 acceptance flags.');
|
|
703
690
|
return;
|
|
704
691
|
}
|
|
705
|
-
const credentialReusabilityConsentGiven = params
|
|
692
|
+
const credentialReusabilityConsentGiven = params.credentialReusabilityConsentGiven ?? false;
|
|
706
693
|
const termsAcceptedAt = new Date().toISOString();
|
|
707
|
-
const disclaimerIds = this.state.
|
|
694
|
+
const disclaimerIds = this.state.disclaimers.map((disclaimer) => disclaimer.id);
|
|
708
695
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
709
|
-
if (params
|
|
696
|
+
if (params.email) {
|
|
710
697
|
state.email = params.email;
|
|
711
698
|
}
|
|
712
|
-
if (params
|
|
699
|
+
if (params.product) {
|
|
713
700
|
state.activeProduct = params.product;
|
|
714
701
|
}
|
|
715
|
-
state.
|
|
716
|
-
state.
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
state.idosDisclaimersAccepted = idosDisclaimersAccepted;
|
|
702
|
+
state.termsAcceptedAt = termsAcceptedAt;
|
|
703
|
+
state.acceptedDisclaimerIds = disclaimerIds;
|
|
704
|
+
state.termsAcceptedVendor = state.activeVendor;
|
|
705
|
+
state.sumsubTncAccepted = sumsubTncSigned;
|
|
706
|
+
state.idosTncAccepted = idosTncSigned;
|
|
721
707
|
state.credentialReusabilityConsentGiven =
|
|
722
708
|
credentialReusabilityConsentGiven;
|
|
723
709
|
});
|
|
724
710
|
if (usesConsentsFlow(this.state.activeVendor)) {
|
|
725
711
|
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, {
|
|
726
|
-
|
|
727
|
-
|
|
712
|
+
sumsubTncSigned,
|
|
713
|
+
idosTncSigned,
|
|
728
714
|
credentialReusabilityConsentGiven,
|
|
729
715
|
});
|
|
730
716
|
return;
|
|
@@ -736,12 +722,7 @@ export class KycController extends BaseController {
|
|
|
736
722
|
*/
|
|
737
723
|
clearSavedTerms() {
|
|
738
724
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
739
|
-
|
|
740
|
-
getDefaultKycVendorDisclaimersAccepted();
|
|
741
|
-
state.providerDisclaimersAccepted =
|
|
742
|
-
getDefaultKycProviderDisclaimersAccepted();
|
|
743
|
-
state.idosDisclaimersAccepted = null;
|
|
744
|
-
state.credentialReusabilityConsentGiven = null;
|
|
725
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
|
|
745
726
|
});
|
|
746
727
|
}
|
|
747
728
|
/**
|
|
@@ -755,7 +736,68 @@ export class KycController extends BaseController {
|
|
|
755
736
|
* @returns An object whose optional `reply` should be posted back.
|
|
756
737
|
*/
|
|
757
738
|
async handleFrameMessage(params) {
|
|
758
|
-
|
|
739
|
+
const payload = params.message;
|
|
740
|
+
if (!payload) {
|
|
741
|
+
return {};
|
|
742
|
+
}
|
|
743
|
+
if (payload.kind === 'handshake') {
|
|
744
|
+
const channelId = payload.meta?.channelId;
|
|
745
|
+
return { reply: { version: 2, meta: { channelId }, kind: 'ack' } };
|
|
746
|
+
}
|
|
747
|
+
if (payload.kind !== 'complete') {
|
|
748
|
+
return {};
|
|
749
|
+
}
|
|
750
|
+
const channelId = payload.meta?.channelId;
|
|
751
|
+
// Only honor a Check/Auth `complete` for the MoonPay frame the flow is
|
|
752
|
+
// currently waiting on. This drops stale or duplicate messages — e.g. a
|
|
753
|
+
// late post after `reset()` (phase `idle`), after the flow already
|
|
754
|
+
// advanced past this frame, or after a vendor switch — so they cannot
|
|
755
|
+
// resurrect tokens, rewind `phase`, or recapture `moonpayCustomerId` on a
|
|
756
|
+
// controller that has moved on. Frame messages are external input and,
|
|
757
|
+
// unlike the async steps, are not covered by the `#generation` guard.
|
|
758
|
+
let expectedPhase = null;
|
|
759
|
+
if (channelId === CHANNEL_CHECK) {
|
|
760
|
+
expectedPhase = 'check';
|
|
761
|
+
}
|
|
762
|
+
else if (channelId === CHANNEL_AUTH) {
|
|
763
|
+
expectedPhase = 'auth';
|
|
764
|
+
}
|
|
765
|
+
if (!expectedPhase ||
|
|
766
|
+
this.state.phase !== expectedPhase ||
|
|
767
|
+
this.state.activeVendor !== 'moonpay') {
|
|
768
|
+
return {};
|
|
769
|
+
}
|
|
770
|
+
const status = payload.payload?.status;
|
|
771
|
+
const credsEnvelope = payload.payload?.credentials;
|
|
772
|
+
const customerId = payload.payload?.customer?.id ?? null;
|
|
773
|
+
if (customerId) {
|
|
774
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
775
|
+
state.moonpayCustomerId = customerId;
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
if (!status) {
|
|
779
|
+
return {};
|
|
780
|
+
}
|
|
781
|
+
let accessToken;
|
|
782
|
+
let clientToken;
|
|
783
|
+
if (credsEnvelope && __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
|
|
784
|
+
try {
|
|
785
|
+
const { credentials } = decryptCredentials(credsEnvelope, __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").privateKey);
|
|
786
|
+
accessToken = credentials.accessToken;
|
|
787
|
+
clientToken = credentials.clientToken;
|
|
788
|
+
}
|
|
789
|
+
catch (error) {
|
|
790
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Failed to decrypt frame credentials: ${String(error)}`);
|
|
791
|
+
return {};
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
if (channelId === CHANNEL_CHECK) {
|
|
795
|
+
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_handleCheckOutcome).call(this, status, accessToken, clientToken);
|
|
796
|
+
return {};
|
|
797
|
+
}
|
|
798
|
+
// channelId === CHANNEL_AUTH, guaranteed by the expectedPhase guard above.
|
|
799
|
+
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_handleAuthOutcome).call(this, status, accessToken);
|
|
800
|
+
return {};
|
|
759
801
|
}
|
|
760
802
|
/**
|
|
761
803
|
* Builds the Check-frame URL, or `null` when no session exists yet.
|
|
@@ -763,7 +805,17 @@ export class KycController extends BaseController {
|
|
|
763
805
|
* @returns The Check-frame URL or `null`.
|
|
764
806
|
*/
|
|
765
807
|
buildCheckFrameUrl() {
|
|
766
|
-
|
|
808
|
+
if (this.state.activeVendor !== 'moonpay' ||
|
|
809
|
+
!this.state.sessionToken ||
|
|
810
|
+
!__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
const url = new URL(`${FRAMES_BASE_URL}/check-connection`);
|
|
814
|
+
url.searchParams.set('sessionToken', this.state.sessionToken);
|
|
815
|
+
url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").publicKeyHex);
|
|
816
|
+
url.searchParams.set('channelId', CHANNEL_CHECK);
|
|
817
|
+
url.searchParams.set('skipKyc', 'true');
|
|
818
|
+
return url.toString();
|
|
767
819
|
}
|
|
768
820
|
/**
|
|
769
821
|
* Builds the Auth-frame URL, or `null` when no client token is available.
|
|
@@ -771,7 +823,16 @@ export class KycController extends BaseController {
|
|
|
771
823
|
* @returns The Auth-frame URL or `null`.
|
|
772
824
|
*/
|
|
773
825
|
buildAuthFrameUrl() {
|
|
774
|
-
|
|
826
|
+
if (this.state.activeVendor !== 'moonpay' ||
|
|
827
|
+
!__classPrivateFieldGet(this, _KycController_authClientToken, "f") ||
|
|
828
|
+
!__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
|
|
829
|
+
return null;
|
|
830
|
+
}
|
|
831
|
+
const url = new URL(`${FRAMES_BASE_URL}/auth`);
|
|
832
|
+
url.searchParams.set('clientToken', __classPrivateFieldGet(this, _KycController_authClientToken, "f"));
|
|
833
|
+
url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").publicKeyHex);
|
|
834
|
+
url.searchParams.set('channelId', CHANNEL_AUTH);
|
|
835
|
+
return url.toString();
|
|
775
836
|
}
|
|
776
837
|
/**
|
|
777
838
|
* Builds the Reset-frame URL.
|
|
@@ -779,7 +840,9 @@ export class KycController extends BaseController {
|
|
|
779
840
|
* @returns The Reset-frame URL.
|
|
780
841
|
*/
|
|
781
842
|
buildResetFrameUrl() {
|
|
782
|
-
|
|
843
|
+
const url = new URL(`${FRAMES_BASE_URL}/reset`);
|
|
844
|
+
url.searchParams.set('channelId', CHANNEL_RESET);
|
|
845
|
+
return url.toString();
|
|
783
846
|
}
|
|
784
847
|
/**
|
|
785
848
|
* Checks whether KYC is required for a product and caches the result.
|
|
@@ -790,9 +853,9 @@ export class KycController extends BaseController {
|
|
|
790
853
|
* @returns Whether KYC is required.
|
|
791
854
|
*/
|
|
792
855
|
async checkKycRequired(params) {
|
|
793
|
-
const {
|
|
794
|
-
if (!
|
|
795
|
-
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing
|
|
856
|
+
const { accessToken } = this.state;
|
|
857
|
+
if (!accessToken) {
|
|
858
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing accessToken — repeat the authentication step.');
|
|
796
859
|
return false;
|
|
797
860
|
}
|
|
798
861
|
const country = params.country ?? this.state.geoCountry;
|
|
@@ -808,11 +871,7 @@ export class KycController extends BaseController {
|
|
|
808
871
|
state.statusMessage = 'Checking KYC status...';
|
|
809
872
|
});
|
|
810
873
|
try {
|
|
811
|
-
const { kycRequired } = await this.messenger.call('KycService:checkKycRequired', {
|
|
812
|
-
accessToken: moonpayAccessToken,
|
|
813
|
-
country,
|
|
814
|
-
capabilities: [{ product: params.product }],
|
|
815
|
-
});
|
|
874
|
+
const { kycRequired } = await this.messenger.call('KycService:checkKycRequired', { accessToken, country, capabilities: [{ product: params.product }] });
|
|
816
875
|
// The flow was reset while the check was in flight; discard the result
|
|
817
876
|
// rather than resurrecting a done/cached state on an idle controller.
|
|
818
877
|
const applied = __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
@@ -1097,11 +1156,13 @@ export class KycController extends BaseController {
|
|
|
1097
1156
|
state.phase = 'idle';
|
|
1098
1157
|
state.statusMessage = '';
|
|
1099
1158
|
state.error = null;
|
|
1100
|
-
state.
|
|
1101
|
-
state.
|
|
1159
|
+
state.disclaimers = [];
|
|
1160
|
+
state.disclaimersError = null;
|
|
1102
1161
|
state.sessionDisclaimers = null;
|
|
1103
1162
|
state.credentialReusabilityConsentGiven = null;
|
|
1104
|
-
|
|
1163
|
+
state.sessionToken = null;
|
|
1164
|
+
state.accessToken = null;
|
|
1165
|
+
state.moonpayCustomerId = null;
|
|
1105
1166
|
state.activeVendor = 'moonpay';
|
|
1106
1167
|
state.activeProduct = null;
|
|
1107
1168
|
state.sumsub = {
|
|
@@ -1128,7 +1189,7 @@ export class KycController extends BaseController {
|
|
|
1128
1189
|
});
|
|
1129
1190
|
}
|
|
1130
1191
|
}
|
|
1131
|
-
_KycController_sumsubLauncher = new WeakMap(),
|
|
1192
|
+
_KycController_sumsubLauncher = new WeakMap(), _KycController_moonpayFrameKeypair = new WeakMap(), _KycController_authClientToken = new WeakMap(), _KycController_generation = new WeakMap(), _KycController_sessionStatusPollIntervalMs = new WeakMap(), _KycController_pollTimer = new WeakMap(), _KycController_pollToken = new WeakMap(), _KycController_userStatusPollIntervalMs = new WeakMap(), _KycController_userStatusPollTimer = new WeakMap(), _KycController_userStatusPolling = new WeakMap(), _KycController_userStatusPollToken = new WeakMap(), _KycController_instances = new WeakSet(), _KycController_localUserSecretStore = function _KycController_localUserSecretStore() {
|
|
1132
1193
|
return {
|
|
1133
1194
|
get: async (path, entropySourceId) => this.messenger.call('UserStorageController:performGetStorage', path, entropySourceId),
|
|
1134
1195
|
set: async (path, value, entropySourceId) => this.messenger.call('UserStorageController:performSetStorage', path, value, entropySourceId),
|
|
@@ -1140,14 +1201,13 @@ _KycController_sumsubLauncher = new WeakMap(), _KycController_moonPayFrames = ne
|
|
|
1140
1201
|
* SumSub — skipping MoonPay Check/Auth frames.
|
|
1141
1202
|
*
|
|
1142
1203
|
* @param consents - T&C2 flags mapped onto the session disclaimer catalog.
|
|
1143
|
-
* @param consents.
|
|
1144
|
-
* @param consents.
|
|
1204
|
+
* @param consents.sumsubTncSigned - Whether Sumsub T&C were accepted.
|
|
1205
|
+
* @param consents.idosTncSigned - Whether idOS T&C were accepted.
|
|
1145
1206
|
* @param consents.credentialReusabilityConsentGiven - Whether credential
|
|
1146
1207
|
* reuse was accepted.
|
|
1147
1208
|
*/
|
|
1148
1209
|
async function _KycController_startConsentsSession(consents) {
|
|
1149
|
-
const { email } = this.state;
|
|
1150
|
-
const acceptedDisclaimerIds = ironDisclaimerIds(this.state.vendorDisclaimersAccepted);
|
|
1210
|
+
const { email, acceptedDisclaimerIds } = this.state;
|
|
1151
1211
|
if (!email) {
|
|
1152
1212
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing email for consents session.');
|
|
1153
1213
|
return;
|
|
@@ -1165,7 +1225,7 @@ async function _KycController_startConsentsSession(consents) {
|
|
|
1165
1225
|
state.sumsub.result = null;
|
|
1166
1226
|
state.sumsub.sessionStatus = null;
|
|
1167
1227
|
// Consents-path vendors have no MoonPay session/access tokens.
|
|
1168
|
-
|
|
1228
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
|
|
1169
1229
|
});
|
|
1170
1230
|
try {
|
|
1171
1231
|
await this.messenger.call('KycService:submitVendorDisclaimers', {
|
|
@@ -1282,8 +1342,8 @@ async function _KycController_startConsentsSession(consents) {
|
|
|
1282
1342
|
*
|
|
1283
1343
|
* @param sessionId - The UKYC session id.
|
|
1284
1344
|
* @param consents - T&C2 flags mapped onto catalog documents.
|
|
1285
|
-
* @param consents.
|
|
1286
|
-
* @param consents.
|
|
1345
|
+
* @param consents.sumsubTncSigned - Whether Sumsub T&C were accepted.
|
|
1346
|
+
* @param consents.idosTncSigned - Whether idOS T&C were accepted.
|
|
1287
1347
|
* @param consents.credentialReusabilityConsentGiven - Whether credential
|
|
1288
1348
|
* reuse was accepted.
|
|
1289
1349
|
* @param generation - Flow generation captured by the caller.
|
|
@@ -1297,12 +1357,12 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
|
|
|
1297
1357
|
state.sessionDisclaimers = catalog;
|
|
1298
1358
|
state.statusMessage = 'Submitting consents...';
|
|
1299
1359
|
});
|
|
1300
|
-
if (isAcceptedCategoryEmpty(catalog.idOS, consents.
|
|
1301
|
-
isAcceptedCategoryEmpty(catalog.kycProvider, consents.
|
|
1360
|
+
if (isAcceptedCategoryEmpty(catalog.idOS, consents.idosTncSigned) ||
|
|
1361
|
+
isAcceptedCategoryEmpty(catalog.kycProvider, consents.sumsubTncSigned)) {
|
|
1302
1362
|
throw new Error('Session disclaimer catalog is missing documents for an accepted category.');
|
|
1303
1363
|
}
|
|
1304
|
-
const idOS =
|
|
1305
|
-
const kycProvider =
|
|
1364
|
+
const idOS = consentRecordsFromCatalog(catalog.idOS, consents.idosTncSigned);
|
|
1365
|
+
const kycProvider = consentRecordsFromCatalog(catalog.kycProvider, consents.sumsubTncSigned);
|
|
1306
1366
|
const reuseUnchanged = catalog.credentialReusabilityConsentGiven ===
|
|
1307
1367
|
consents.credentialReusabilityConsentGiven;
|
|
1308
1368
|
if (idOS.length === 0 && kycProvider.length === 0 && reuseUnchanged) {
|
|
@@ -1333,9 +1393,8 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
|
|
|
1333
1393
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1334
1394
|
state.sessionDisclaimers = latest;
|
|
1335
1395
|
});
|
|
1336
|
-
|
|
1337
|
-
const
|
|
1338
|
-
const stillMissingProvider = acceptedCategoryStillMissing(latest.kycProvider, consents.providerDisclaimersAccepted);
|
|
1396
|
+
const stillMissingIdos = acceptedCategoryStillMissing(latest.idOS, consents.idosTncSigned);
|
|
1397
|
+
const stillMissingProvider = acceptedCategoryStillMissing(latest.kycProvider, consents.sumsubTncSigned);
|
|
1339
1398
|
const stillMissingReuse = consents.credentialReusabilityConsentGiven &&
|
|
1340
1399
|
!latest.credentialReusabilityConsentGiven;
|
|
1341
1400
|
if (stillMissingIdos || stillMissingProvider || stillMissingReuse) {
|
|
@@ -1347,9 +1406,7 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
|
|
|
1347
1406
|
* Creates a vendor session from the currently stored terms + email.
|
|
1348
1407
|
*/
|
|
1349
1408
|
async function _KycController_createSession() {
|
|
1350
|
-
const { email } = this.state;
|
|
1351
|
-
const termsAcceptedAt = this.state.vendorDisclaimersAccepted.moonpay?.termsAcceptedAt;
|
|
1352
|
-
const acceptedDisclaimerIds = this.state.vendorDisclaimers.map((disclaimer) => disclaimer.id);
|
|
1409
|
+
const { email, termsAcceptedAt, acceptedDisclaimerIds } = this.state;
|
|
1353
1410
|
if (!email) {
|
|
1354
1411
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing email for session creation.');
|
|
1355
1412
|
return;
|
|
@@ -1364,7 +1421,7 @@ async function _KycController_createSession() {
|
|
|
1364
1421
|
// (or, on failure, invalid) session token, `buildAuthFrameUrl` cannot
|
|
1365
1422
|
// return a URL tied to an old client token, and `checkKycRequired` cannot
|
|
1366
1423
|
// run with an access token from an earlier authentication. The Check/Auth
|
|
1367
|
-
// frames re-populate these for the new session. Because `
|
|
1424
|
+
// frames re-populate these for the new session. Because `sessionToken` is
|
|
1368
1425
|
// cleared here and only re-set on success, a failed creation leaves it
|
|
1369
1426
|
// `null` rather than resurrecting the previous session.
|
|
1370
1427
|
// Capture the flow generation so a `reset()` landing while the create
|
|
@@ -1372,18 +1429,18 @@ async function _KycController_createSession() {
|
|
|
1372
1429
|
// the now-idle controller (failure). The synchronous update below runs
|
|
1373
1430
|
// before any `await`, so it needs no guard.
|
|
1374
1431
|
const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
|
|
1375
|
-
|
|
1432
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
|
|
1376
1433
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1377
1434
|
state.error = null;
|
|
1378
1435
|
state.phase = 'session';
|
|
1379
1436
|
state.statusMessage = 'Creating session...';
|
|
1380
|
-
state.
|
|
1381
|
-
state.
|
|
1437
|
+
state.sessionToken = null;
|
|
1438
|
+
state.accessToken = null;
|
|
1382
1439
|
});
|
|
1383
1440
|
try {
|
|
1384
1441
|
const { sessionToken } = await this.messenger.call('KycService:createSession', { email, termsAcceptedAt, disclaimerIds: acceptedDisclaimerIds });
|
|
1385
1442
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
1386
|
-
state.
|
|
1443
|
+
state.sessionToken = sessionToken;
|
|
1387
1444
|
state.phase = 'check';
|
|
1388
1445
|
state.statusMessage = 'Authenticating via Check frame...';
|
|
1389
1446
|
});
|
|
@@ -1409,13 +1466,82 @@ async function _KycController_createSession() {
|
|
|
1409
1466
|
});
|
|
1410
1467
|
await this.loadDisclaimers();
|
|
1411
1468
|
}
|
|
1412
|
-
}, _KycController_clearAcceptedTerms = function _KycController_clearAcceptedTerms(state
|
|
1413
|
-
|
|
1414
|
-
state.
|
|
1415
|
-
state.
|
|
1416
|
-
|
|
1417
|
-
state.
|
|
1469
|
+
}, _KycController_clearAcceptedTerms = function _KycController_clearAcceptedTerms(state) {
|
|
1470
|
+
state.termsAcceptedAt = null;
|
|
1471
|
+
state.acceptedDisclaimerIds = [];
|
|
1472
|
+
state.termsAcceptedVendor = null;
|
|
1473
|
+
state.sumsubTncAccepted = null;
|
|
1474
|
+
state.idosTncAccepted = null;
|
|
1418
1475
|
state.credentialReusabilityConsentGiven = null;
|
|
1476
|
+
}, _KycController_clearMoonPaySession = function _KycController_clearMoonPaySession(state) {
|
|
1477
|
+
state.moonpayCustomerId = null;
|
|
1478
|
+
state.sessionToken = null;
|
|
1479
|
+
state.accessToken = null;
|
|
1480
|
+
}, _KycController_dropTermsUnlessForVendor = function _KycController_dropTermsUnlessForVendor(vendor) {
|
|
1481
|
+
if (__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_hasTermsForVendor).call(this, vendor)) {
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1485
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
|
|
1486
|
+
});
|
|
1487
|
+
}, _KycController_hasTermsForVendor = function _KycController_hasTermsForVendor(vendor) {
|
|
1488
|
+
if (this.state.termsAcceptedVendor === null) {
|
|
1489
|
+
return false;
|
|
1490
|
+
}
|
|
1491
|
+
return this.state.termsAcceptedVendor === vendor;
|
|
1492
|
+
}, _KycController_handleCheckOutcome =
|
|
1493
|
+
/**
|
|
1494
|
+
* Applies a Check-frame outcome.
|
|
1495
|
+
*
|
|
1496
|
+
* @param status - The frame status.
|
|
1497
|
+
* @param accessToken - The decrypted access token, if any.
|
|
1498
|
+
* @param clientToken - The decrypted client token, if any.
|
|
1499
|
+
*/
|
|
1500
|
+
async function _KycController_handleCheckOutcome(status, accessToken, clientToken) {
|
|
1501
|
+
if (status === 'active' && accessToken) {
|
|
1502
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1503
|
+
state.accessToken = accessToken;
|
|
1504
|
+
state.phase = 'form';
|
|
1505
|
+
state.statusMessage = 'Already authenticated. Review to submit.';
|
|
1506
|
+
});
|
|
1507
|
+
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this);
|
|
1508
|
+
return;
|
|
1509
|
+
}
|
|
1510
|
+
if (status === 'connectionRequired' && clientToken) {
|
|
1511
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, clientToken, "f");
|
|
1512
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1513
|
+
state.phase = 'auth';
|
|
1514
|
+
state.statusMessage = 'Verify your email via OTP in the Auth frame.';
|
|
1515
|
+
});
|
|
1516
|
+
return;
|
|
1517
|
+
}
|
|
1518
|
+
if (status === 'termsAcceptanceRequired') {
|
|
1519
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this);
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Check frame returned status: ${status}`);
|
|
1523
|
+
}, _KycController_handleAuthOutcome =
|
|
1524
|
+
/**
|
|
1525
|
+
* Applies an Auth-frame outcome.
|
|
1526
|
+
*
|
|
1527
|
+
* @param status - The frame status.
|
|
1528
|
+
* @param accessToken - The decrypted access token, if any.
|
|
1529
|
+
*/
|
|
1530
|
+
async function _KycController_handleAuthOutcome(status, accessToken) {
|
|
1531
|
+
if (status === 'active' && accessToken) {
|
|
1532
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1533
|
+
state.accessToken = accessToken;
|
|
1534
|
+
state.phase = 'form';
|
|
1535
|
+
state.statusMessage = 'Authenticated. Review to submit.';
|
|
1536
|
+
});
|
|
1537
|
+
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this);
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
if (status === 'termsAcceptanceRequired') {
|
|
1541
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this);
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Auth frame returned status: ${status}`);
|
|
1419
1545
|
}, _KycController_continueAfterAuthentication =
|
|
1420
1546
|
/**
|
|
1421
1547
|
* Continues the flow once authentication has completed (phase `form`).
|
|
@@ -1467,7 +1593,7 @@ async function _KycController_continueAfterAuthentication() {
|
|
|
1467
1593
|
return {
|
|
1468
1594
|
vendor: 'moonpay',
|
|
1469
1595
|
vendorMetadata: {
|
|
1470
|
-
moonPayAccessToken: this.state.
|
|
1596
|
+
moonPayAccessToken: this.state.accessToken,
|
|
1471
1597
|
moonPayUserId: this.state.moonpayCustomerId,
|
|
1472
1598
|
},
|
|
1473
1599
|
};
|
|
@@ -1535,8 +1661,7 @@ async function _KycController_createUkycSession(generation) {
|
|
|
1535
1661
|
// authorizes later storage reads without granting write or delete access.
|
|
1536
1662
|
const ukycCapabilityToken = signStorageAccessToken({
|
|
1537
1663
|
material: clientMaterial,
|
|
1538
|
-
|
|
1539
|
-
operations: ['read', 'write'],
|
|
1664
|
+
operations: ['read'],
|
|
1540
1665
|
expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),
|
|
1541
1666
|
});
|
|
1542
1667
|
const wrappedUkycCapabilityToken = wrapEncryptionKey(sessionClientPrivateKey, capabilityTokenSchema.serverPublicKey.x, stringToBytes(encodeStorageAccessTokenForHeader(ukycCapabilityToken)));
|
|
@@ -1723,7 +1848,7 @@ async function _KycController_pollSessionStatusOnce(sessionId, token) {
|
|
|
1723
1848
|
__classPrivateFieldSet(this, _KycController_pollTimer, null, "f");
|
|
1724
1849
|
}
|
|
1725
1850
|
}, _KycController_cancelPendingSession = function _KycController_cancelPendingSession() {
|
|
1726
|
-
|
|
1851
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
|
|
1727
1852
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopPolling).call(this);
|
|
1728
1853
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopUserStatusPolling).call(this);
|
|
1729
1854
|
__classPrivateFieldSet(this, _KycController_generation, __classPrivateFieldGet(this, _KycController_generation, "f") + 1, "f");
|