@metamask-previews/kyc-controller 0.0.0-preview-abca9bcea → 0.0.0-preview-ec24abb79
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 -12
- 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 +300 -191
- package/dist/KycController.cjs.map +1 -1
- package/dist/KycController.d.cts +40 -46
- package/dist/KycController.d.cts.map +1 -1
- package/dist/KycController.d.mts +40 -46
- package/dist/KycController.d.mts.map +1 -1
- package/dist/KycController.mjs +299 -188
- 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 +6 -23
- package/dist/KycService-method-action-types.d.cts.map +1 -1
- package/dist/KycService-method-action-types.d.mts +6 -23
- package/dist/KycService-method-action-types.d.mts.map +1 -1
- package/dist/KycService-method-action-types.mjs.map +1 -1
- package/dist/KycService.cjs +119 -100
- package/dist/KycService.cjs.map +1 -1
- package/dist/KycService.d.cts +12 -38
- package/dist/KycService.d.cts.map +1 -1
- package/dist/KycService.d.mts +12 -38
- package/dist/KycService.d.mts.map +1 -1
- package/dist/KycService.mjs +119 -100
- 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 +4 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +4 -4
- 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 +5 -53
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +5 -53
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/ukyc/wrapEncryptionKey.cjs +9 -4
- package/dist/ukyc/wrapEncryptionKey.cjs.map +1 -1
- package/dist/ukyc/wrapEncryptionKey.d.cts +10 -8
- package/dist/ukyc/wrapEncryptionKey.d.cts.map +1 -1
- package/dist/ukyc/wrapEncryptionKey.d.mts +10 -8
- package/dist/ukyc/wrapEncryptionKey.d.mts.map +1 -1
- package/dist/ukyc/wrapEncryptionKey.mjs +9 -4
- package/dist/ukyc/wrapEncryptionKey.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/logger.cjs +0 -9
- package/dist/logger.cjs.map +0 -1
- package/dist/logger.d.cts +0 -6
- package/dist/logger.d.cts.map +0 -1
- package/dist/logger.d.mts +0 -6
- package/dist/logger.d.mts.map +0 -1
- package/dist/logger.mjs +0 -6
- package/dist/logger.mjs.map +0 -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.cjs
CHANGED
|
@@ -10,23 +10,25 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
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");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _KycController_instances, _KycController_sumsubLauncher,
|
|
13
|
+
var _KycController_instances, _KycController_sumsubLauncher, _KycController_keypair, _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;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.KycController = exports.getDefaultKycControllerState = exports.
|
|
15
|
+
exports.KycController = exports.getDefaultKycControllerState = exports.controllerName = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
17
17
|
const utils_1 = require("@metamask/utils");
|
|
18
18
|
const ed25519_1 = require("@noble/curves/ed25519");
|
|
19
|
+
const crypto_js_1 = require("./crypto.cjs");
|
|
19
20
|
const encoding_js_1 = require("./encoding.cjs");
|
|
20
|
-
const logger_js_1 = require("./logger.cjs");
|
|
21
21
|
const deriveClientMaterial_js_1 = require("./ukyc/deriveClientMaterial.cjs");
|
|
22
22
|
const jwtChain_js_1 = require("./ukyc/jwtChain.cjs");
|
|
23
23
|
const localUserSecret_js_1 = require("./ukyc/localUserSecret.cjs");
|
|
24
24
|
const storageAccessToken_js_1 = require("./ukyc/storageAccessToken.cjs");
|
|
25
25
|
const wrapEncryptionKey_js_1 = require("./ukyc/wrapEncryptionKey.cjs");
|
|
26
|
-
const vendorDisclaimerAcceptance_js_1 = require("./vendorDisclaimerAcceptance.cjs");
|
|
27
|
-
const MoonPayFrameHandler_js_1 = require("./vendors/MoonPayFrameHandler.cjs");
|
|
28
26
|
// === GENERAL ===
|
|
29
27
|
exports.controllerName = 'KycController';
|
|
28
|
+
const FRAMES_BASE_URL = 'https://blocks.moonpay.com/platform/v1';
|
|
29
|
+
const CHANNEL_CHECK = 'ch_1';
|
|
30
|
+
const CHANNEL_AUTH = 'ch_2';
|
|
31
|
+
const CHANNEL_RESET = 'ch_reset';
|
|
30
32
|
// Placeholder credentials for the SumSub sub-flow. These are demo values that
|
|
31
33
|
// must be replaced with real UKYC-issued material before production use.
|
|
32
34
|
const MOCK_JWT_TOKEN = 'mock-jwt-token';
|
|
@@ -117,19 +119,31 @@ const kycControllerMetadata = {
|
|
|
117
119
|
persist: false,
|
|
118
120
|
usedInUi: false,
|
|
119
121
|
},
|
|
120
|
-
|
|
122
|
+
termsAcceptedAt: {
|
|
121
123
|
includeInDebugSnapshot: true,
|
|
122
124
|
includeInStateLogs: true,
|
|
123
125
|
persist: true,
|
|
124
126
|
usedInUi: false,
|
|
125
127
|
},
|
|
126
|
-
|
|
128
|
+
acceptedDisclaimerIds: {
|
|
127
129
|
includeInDebugSnapshot: true,
|
|
128
130
|
includeInStateLogs: true,
|
|
129
131
|
persist: true,
|
|
130
132
|
usedInUi: false,
|
|
131
133
|
},
|
|
132
|
-
|
|
134
|
+
termsAcceptedVendor: {
|
|
135
|
+
includeInDebugSnapshot: true,
|
|
136
|
+
includeInStateLogs: true,
|
|
137
|
+
persist: true,
|
|
138
|
+
usedInUi: false,
|
|
139
|
+
},
|
|
140
|
+
sumsubTncAccepted: {
|
|
141
|
+
includeInDebugSnapshot: true,
|
|
142
|
+
includeInStateLogs: true,
|
|
143
|
+
persist: true,
|
|
144
|
+
usedInUi: false,
|
|
145
|
+
},
|
|
146
|
+
idosTncAccepted: {
|
|
133
147
|
includeInDebugSnapshot: true,
|
|
134
148
|
includeInStateLogs: true,
|
|
135
149
|
persist: true,
|
|
@@ -141,13 +155,13 @@ const kycControllerMetadata = {
|
|
|
141
155
|
persist: false,
|
|
142
156
|
usedInUi: false,
|
|
143
157
|
},
|
|
144
|
-
|
|
158
|
+
disclaimers: {
|
|
145
159
|
includeInDebugSnapshot: false,
|
|
146
160
|
includeInStateLogs: false,
|
|
147
161
|
persist: false,
|
|
148
162
|
usedInUi: true,
|
|
149
163
|
},
|
|
150
|
-
|
|
164
|
+
disclaimersError: {
|
|
151
165
|
includeInDebugSnapshot: true,
|
|
152
166
|
includeInStateLogs: true,
|
|
153
167
|
persist: false,
|
|
@@ -165,13 +179,13 @@ const kycControllerMetadata = {
|
|
|
165
179
|
persist: false,
|
|
166
180
|
usedInUi: true,
|
|
167
181
|
},
|
|
168
|
-
|
|
182
|
+
sessionToken: {
|
|
169
183
|
includeInDebugSnapshot: false,
|
|
170
184
|
includeInStateLogs: false,
|
|
171
185
|
persist: false,
|
|
172
186
|
usedInUi: false,
|
|
173
187
|
},
|
|
174
|
-
|
|
188
|
+
accessToken: {
|
|
175
189
|
includeInDebugSnapshot: false,
|
|
176
190
|
includeInStateLogs: false,
|
|
177
191
|
persist: false,
|
|
@@ -232,19 +246,6 @@ const kycControllerMetadata = {
|
|
|
232
246
|
usedInUi: true,
|
|
233
247
|
},
|
|
234
248
|
};
|
|
235
|
-
/**
|
|
236
|
-
* Constructs the default {@link KycVendorDisclaimersAccepted} value.
|
|
237
|
-
*
|
|
238
|
-
* @returns The default vendor-disclaimer acceptance map.
|
|
239
|
-
*/
|
|
240
|
-
function getDefaultKycVendorDisclaimersAccepted() {
|
|
241
|
-
return { moonpay: null, iron: null };
|
|
242
|
-
}
|
|
243
|
-
exports.getDefaultKycVendorDisclaimersAccepted = getDefaultKycVendorDisclaimersAccepted;
|
|
244
|
-
function getDefaultKycProviderDisclaimersAccepted() {
|
|
245
|
-
return { sumsub: null };
|
|
246
|
-
}
|
|
247
|
-
exports.getDefaultKycProviderDisclaimersAccepted = getDefaultKycProviderDisclaimersAccepted;
|
|
248
249
|
/**
|
|
249
250
|
* Constructs the default {@link KycController} state.
|
|
250
251
|
*
|
|
@@ -256,16 +257,18 @@ function getDefaultKycControllerState() {
|
|
|
256
257
|
statusMessage: '',
|
|
257
258
|
error: null,
|
|
258
259
|
email: null,
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
termsAcceptedAt: null,
|
|
261
|
+
acceptedDisclaimerIds: [],
|
|
262
|
+
termsAcceptedVendor: null,
|
|
263
|
+
sumsubTncAccepted: null,
|
|
264
|
+
idosTncAccepted: null,
|
|
262
265
|
credentialReusabilityConsentGiven: null,
|
|
263
|
-
|
|
264
|
-
|
|
266
|
+
disclaimers: [],
|
|
267
|
+
disclaimersError: null,
|
|
265
268
|
sessionDisclaimers: null,
|
|
266
269
|
geoCountry: null,
|
|
267
|
-
|
|
268
|
-
|
|
270
|
+
sessionToken: null,
|
|
271
|
+
accessToken: null,
|
|
269
272
|
moonpayCustomerId: null,
|
|
270
273
|
activeVendor: 'moonpay',
|
|
271
274
|
activeProduct: null,
|
|
@@ -310,62 +313,45 @@ function isConsentConflictError(error) {
|
|
|
310
313
|
error.httpStatus === 409);
|
|
311
314
|
}
|
|
312
315
|
/**
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*/
|
|
317
|
-
function isValidConsentRecordList(value) {
|
|
318
|
-
return (Array.isArray(value) &&
|
|
319
|
-
value.every((item) => typeof item === 'object' &&
|
|
320
|
-
item !== null &&
|
|
321
|
-
typeof item.key === 'string' &&
|
|
322
|
-
typeof item.version === 'string'));
|
|
323
|
-
}
|
|
324
|
-
/**
|
|
325
|
-
* Maps accepted disclaimer records onto unconsented catalog documents.
|
|
316
|
+
* Maps a session-disclaimer catalog into the `{ key, version }` records the
|
|
317
|
+
* record-consents API expects, or an empty list when the user declined that
|
|
318
|
+
* category.
|
|
326
319
|
*
|
|
327
320
|
* @param documents - Catalog documents for one consent category.
|
|
328
|
-
* @param accepted -
|
|
329
|
-
* @returns Consent records
|
|
321
|
+
* @param accepted - Whether the user accepted that category.
|
|
322
|
+
* @returns Consent records, or `[]` when not accepted.
|
|
330
323
|
*/
|
|
331
|
-
function
|
|
332
|
-
if (accepted
|
|
324
|
+
function consentRecordsFromCatalog(documents, accepted) {
|
|
325
|
+
if (!accepted) {
|
|
333
326
|
return [];
|
|
334
327
|
}
|
|
335
|
-
const acceptedKeys = new Set(accepted.map((record) => `${record.key}:${record.version}`));
|
|
336
328
|
return documents
|
|
337
|
-
.filter((document) => !document.consented
|
|
338
|
-
acceptedKeys.has(`${document.key}:${document.version}`))
|
|
329
|
+
.filter((document) => !document.consented)
|
|
339
330
|
.map(({ key, version }) => ({ key, version }));
|
|
340
331
|
}
|
|
341
332
|
/**
|
|
342
|
-
* Whether accepted
|
|
333
|
+
* Whether an accepted T&C2 category has no catalog documents. An empty list
|
|
334
|
+
* would otherwise skip the POST and count as success.
|
|
343
335
|
*
|
|
344
336
|
* @param documents - Catalog documents for one consent category.
|
|
345
|
-
* @param accepted -
|
|
346
|
-
* @returns `true` when the
|
|
337
|
+
* @param accepted - Whether the user accepted that category.
|
|
338
|
+
* @returns `true` when the user accepted and the catalog is empty.
|
|
347
339
|
*/
|
|
348
340
|
function isAcceptedCategoryEmpty(documents, accepted) {
|
|
349
|
-
return accepted
|
|
341
|
+
return accepted && documents.length === 0;
|
|
350
342
|
}
|
|
351
343
|
/**
|
|
352
|
-
* Whether accepted
|
|
353
|
-
* empty catalog or any
|
|
344
|
+
* Whether an accepted category is still missing consent after a 409 re-GET:
|
|
345
|
+
* empty catalog or any document still unconsented.
|
|
354
346
|
*
|
|
355
347
|
* @param documents - Latest catalog documents for one consent category.
|
|
356
|
-
* @param accepted -
|
|
348
|
+
* @param accepted - Whether the user accepted that category.
|
|
357
349
|
* @returns `true` when accepted documents are not fully consented.
|
|
358
350
|
*/
|
|
359
351
|
function acceptedCategoryStillMissing(documents, accepted) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (documents.length === 0) {
|
|
364
|
-
return true;
|
|
365
|
-
}
|
|
366
|
-
const acceptedKeys = new Set(accepted.map((record) => `${record.key}:${record.version}`));
|
|
367
|
-
const relevant = documents.filter((document) => acceptedKeys.has(`${document.key}:${document.version}`));
|
|
368
|
-
return (relevant.length === 0 || relevant.some((document) => !document.consented));
|
|
352
|
+
return (accepted &&
|
|
353
|
+
(documents.length === 0 ||
|
|
354
|
+
documents.some((document) => !document.consented)));
|
|
369
355
|
}
|
|
370
356
|
/**
|
|
371
357
|
* Vendors other than MoonPay skip Check/Auth frames and use the empty-shell
|
|
@@ -401,9 +387,9 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
401
387
|
/**
|
|
402
388
|
* `KycController` orchestrates the vendor-backed KYC / identity-verification
|
|
403
389
|
* flow (MoonPay identity + SumSub documents) behind a vendor-neutral, per
|
|
404
|
-
* product surface used by ramps and card. It owns all state
|
|
405
|
-
* orchestration (via `KycService`),
|
|
406
|
-
* platform-specific presentation (WebView/iframe, SumSub SDK)
|
|
390
|
+
* product surface used by ramps and card. It owns all state, HTTP
|
|
391
|
+
* orchestration (via `KycService`), crypto, and the frame message protocol;
|
|
392
|
+
* platform-specific presentation (WebView/iframe, SumSub SDK) is injected.
|
|
407
393
|
*/
|
|
408
394
|
class KycController extends base_controller_1.BaseController {
|
|
409
395
|
/**
|
|
@@ -427,8 +413,10 @@ class KycController extends base_controller_1.BaseController {
|
|
|
427
413
|
});
|
|
428
414
|
_KycController_instances.add(this);
|
|
429
415
|
_KycController_sumsubLauncher.set(this, void 0);
|
|
430
|
-
/**
|
|
431
|
-
|
|
416
|
+
/** Ephemeral X25519 keypair for the frame key exchange (never persisted). */
|
|
417
|
+
_KycController_keypair.set(this, void 0);
|
|
418
|
+
/** Auth-frame client token, kept out of state. */
|
|
419
|
+
_KycController_authClientToken.set(this, null);
|
|
432
420
|
/**
|
|
433
421
|
* Monotonic flow generation. Incremented by {@link reset} and
|
|
434
422
|
* {@link clearState} so in-flight async work (e.g. the KYC-required check)
|
|
@@ -465,13 +453,7 @@ class KycController extends base_controller_1.BaseController {
|
|
|
465
453
|
__classPrivateFieldSet(this, _KycController_sumsubLauncher, sumsubLauncher, "f");
|
|
466
454
|
__classPrivateFieldSet(this, _KycController_sessionStatusPollIntervalMs, sessionStatusPollIntervalMs, "f");
|
|
467
455
|
__classPrivateFieldSet(this, _KycController_userStatusPollIntervalMs, userStatusPollIntervalMs, "f");
|
|
468
|
-
__classPrivateFieldSet(this,
|
|
469
|
-
getState: () => this.state,
|
|
470
|
-
update: (updater) => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, updater),
|
|
471
|
-
fail: (message) => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, message),
|
|
472
|
-
onAuthenticated: async () => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this),
|
|
473
|
-
requireTermsReacceptance: () => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this),
|
|
474
|
-
}), "f");
|
|
456
|
+
__classPrivateFieldSet(this, _KycController_keypair, (0, crypto_js_1.generateKeyPair)(), "f");
|
|
475
457
|
this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
|
|
476
458
|
}
|
|
477
459
|
/**
|
|
@@ -494,19 +476,10 @@ class KycController extends base_controller_1.BaseController {
|
|
|
494
476
|
// forces `phase` back through `session`/`check`, breaking an in-flight
|
|
495
477
|
// Check/Auth frame flow. Leave the active flow untouched and let the
|
|
496
478
|
// consumer drive it (or call `reset` first to start over).
|
|
497
|
-
const vendor = params?.vendor ?? 'moonpay';
|
|
498
479
|
if (IN_PROGRESS_PHASES.includes(this.state.phase)) {
|
|
499
|
-
if (vendor === 'moonpay') {
|
|
500
|
-
__classPrivateFieldGet(this, _KycController_moonPayFrames, "f").ensureKeypair();
|
|
501
|
-
}
|
|
502
480
|
return;
|
|
503
481
|
}
|
|
504
|
-
|
|
505
|
-
__classPrivateFieldGet(this, _KycController_moonPayFrames, "f").startFlow();
|
|
506
|
-
}
|
|
507
|
-
else {
|
|
508
|
-
__classPrivateFieldGet(this, _KycController_moonPayFrames, "f").clear();
|
|
509
|
-
}
|
|
482
|
+
const vendor = params?.vendor ?? 'moonpay';
|
|
510
483
|
// `initialize` starts a fresh flow, so `activeProduct` is always reset to
|
|
511
484
|
// this call's product (or `null`). Otherwise a prior run's product could
|
|
512
485
|
// linger and cause `#continueAfterAuthentication` to auto-run the check /
|
|
@@ -516,9 +489,14 @@ class KycController extends base_controller_1.BaseController {
|
|
|
516
489
|
state.email = params.email;
|
|
517
490
|
}
|
|
518
491
|
state.activeVendor = vendor;
|
|
519
|
-
// MoonPay Check/Auth artifacts must not survive a switch to another
|
|
492
|
+
// MoonPay Check/Auth artifacts must not survive a switch to another
|
|
493
|
+
// vendor: leftover `sessionToken` would keep `buildCheckFrameUrl` alive,
|
|
494
|
+
// leftover `accessToken` / `#authClientToken` would keep Auth / KYC
|
|
495
|
+
// calls bound to MoonPay, and leftover `moonpayCustomerId` would make
|
|
496
|
+
// `getCustomerIdentity` report a MoonPay id under the wrong vendor.
|
|
520
497
|
if (vendor !== 'moonpay') {
|
|
521
|
-
(
|
|
498
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
|
|
499
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
|
|
522
500
|
}
|
|
523
501
|
state.activeProduct = params?.product ?? null;
|
|
524
502
|
});
|
|
@@ -566,14 +544,16 @@ class KycController extends base_controller_1.BaseController {
|
|
|
566
544
|
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
567
545
|
return;
|
|
568
546
|
}
|
|
569
|
-
|
|
547
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_dropTermsUnlessForVendor).call(this, vendor);
|
|
548
|
+
const hasTerms = Boolean(this.state.termsAcceptedAt) &&
|
|
549
|
+
this.state.acceptedDisclaimerIds.length > 0;
|
|
570
550
|
if (hasTerms && this.state.email) {
|
|
571
551
|
if (usesConsentsFlow(vendor)) {
|
|
572
552
|
// Consents-path vendors require T&C2 flags; if they weren't persisted
|
|
573
553
|
// (i.e. null from pre-migration state), require reacceptance.
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
-
|
|
554
|
+
const sumsubTncSigned = this.state.sumsubTncAccepted;
|
|
555
|
+
const idosTncSigned = this.state.idosTncAccepted;
|
|
556
|
+
if (sumsubTncSigned === null || idosTncSigned === null) {
|
|
577
557
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
578
558
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
|
|
579
559
|
state.phase = 'terms';
|
|
@@ -582,19 +562,12 @@ class KycController extends base_controller_1.BaseController {
|
|
|
582
562
|
return;
|
|
583
563
|
}
|
|
584
564
|
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, {
|
|
585
|
-
|
|
586
|
-
|
|
565
|
+
sumsubTncSigned,
|
|
566
|
+
idosTncSigned,
|
|
587
567
|
credentialReusabilityConsentGiven: this.state.credentialReusabilityConsentGiven ?? false,
|
|
588
568
|
});
|
|
589
569
|
}
|
|
590
570
|
else {
|
|
591
|
-
// TODO: should this be here? or should it exist at all?
|
|
592
|
-
if (vendor === 'moonpay' && this.state.vendorDisclaimers.length === 0) {
|
|
593
|
-
await this.loadDisclaimers();
|
|
594
|
-
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
571
|
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_createSession).call(this);
|
|
599
572
|
}
|
|
600
573
|
return;
|
|
@@ -628,8 +601,8 @@ class KycController extends base_controller_1.BaseController {
|
|
|
628
601
|
// after this request succeeds.
|
|
629
602
|
state.activeVendor = params.vendor;
|
|
630
603
|
if (params.vendor !== 'moonpay') {
|
|
631
|
-
|
|
632
|
-
(
|
|
604
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
|
|
605
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
|
|
633
606
|
}
|
|
634
607
|
});
|
|
635
608
|
const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
|
|
@@ -638,6 +611,10 @@ class KycController extends base_controller_1.BaseController {
|
|
|
638
611
|
vendor: params.vendor,
|
|
639
612
|
email: params.email,
|
|
640
613
|
});
|
|
614
|
+
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_dropTermsUnlessForVendor).call(this, params.vendor);
|
|
641
618
|
}
|
|
642
619
|
catch (error) {
|
|
643
620
|
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
@@ -666,18 +643,18 @@ class KycController extends base_controller_1.BaseController {
|
|
|
666
643
|
state.geoCountry = country;
|
|
667
644
|
});
|
|
668
645
|
}
|
|
669
|
-
const disclaimers = await this.messenger.call('KycService:
|
|
646
|
+
const disclaimers = await this.messenger.call('KycService:fetchDisclaimers', {
|
|
670
647
|
vendor: this.state.activeVendor,
|
|
671
648
|
country,
|
|
672
649
|
});
|
|
673
650
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
674
|
-
state.
|
|
675
|
-
state.
|
|
651
|
+
state.disclaimers = disclaimers;
|
|
652
|
+
state.disclaimersError = null;
|
|
676
653
|
});
|
|
677
654
|
}
|
|
678
655
|
catch (error) {
|
|
679
656
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
680
|
-
state.
|
|
657
|
+
state.disclaimersError = `Failed to load disclaimers: ${String(error)}`;
|
|
681
658
|
});
|
|
682
659
|
}
|
|
683
660
|
}
|
|
@@ -690,47 +667,44 @@ class KycController extends base_controller_1.BaseController {
|
|
|
690
667
|
* @param params.product - The consuming feature the flow runs for. See
|
|
691
668
|
* {@link initialize} for how the product drives the automatic post
|
|
692
669
|
* authentication continuation.
|
|
693
|
-
* @param params.
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
* customer accepted (`{ key, version }` records). Required for every vendor
|
|
698
|
-
* so callers explicitly declare acceptance.
|
|
670
|
+
* @param params.sumsubTncSigned - Whether Sumsub T&C were accepted (T&C2).
|
|
671
|
+
* Required for every vendor so callers explicitly declare acceptance.
|
|
672
|
+
* @param params.idosTncSigned - Whether idOS T&C were accepted (T&C2).
|
|
673
|
+
* Required for every vendor so callers explicitly declare acceptance.
|
|
699
674
|
* @param params.credentialReusabilityConsentGiven - Whether the customer
|
|
700
675
|
* consented to reuse existing idOS credentials. Used when recording
|
|
701
676
|
* session-scoped disclaimers on the consents path. Defaults to `false`.
|
|
702
677
|
*/
|
|
703
678
|
async acceptTermsAndStartSession(params) {
|
|
704
|
-
const
|
|
705
|
-
const
|
|
706
|
-
if (
|
|
707
|
-
|
|
679
|
+
const sumsubTncSigned = params?.sumsubTncSigned;
|
|
680
|
+
const idosTncSigned = params?.idosTncSigned;
|
|
681
|
+
if (typeof sumsubTncSigned !== 'boolean' ||
|
|
682
|
+
typeof idosTncSigned !== 'boolean') {
|
|
708
683
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing T&C2 acceptance flags.');
|
|
709
684
|
return;
|
|
710
685
|
}
|
|
711
|
-
const credentialReusabilityConsentGiven = params
|
|
686
|
+
const credentialReusabilityConsentGiven = params.credentialReusabilityConsentGiven ?? false;
|
|
712
687
|
const termsAcceptedAt = new Date().toISOString();
|
|
713
|
-
const disclaimerIds = this.state.
|
|
688
|
+
const disclaimerIds = this.state.disclaimers.map((disclaimer) => disclaimer.id);
|
|
714
689
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
715
|
-
if (params
|
|
690
|
+
if (params.email) {
|
|
716
691
|
state.email = params.email;
|
|
717
692
|
}
|
|
718
|
-
if (params
|
|
693
|
+
if (params.product) {
|
|
719
694
|
state.activeProduct = params.product;
|
|
720
695
|
}
|
|
721
|
-
state.
|
|
722
|
-
state.
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
state.idosDisclaimersAccepted = idosDisclaimersAccepted;
|
|
696
|
+
state.termsAcceptedAt = termsAcceptedAt;
|
|
697
|
+
state.acceptedDisclaimerIds = disclaimerIds;
|
|
698
|
+
state.termsAcceptedVendor = state.activeVendor;
|
|
699
|
+
state.sumsubTncAccepted = sumsubTncSigned;
|
|
700
|
+
state.idosTncAccepted = idosTncSigned;
|
|
727
701
|
state.credentialReusabilityConsentGiven =
|
|
728
702
|
credentialReusabilityConsentGiven;
|
|
729
703
|
});
|
|
730
704
|
if (usesConsentsFlow(this.state.activeVendor)) {
|
|
731
705
|
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, {
|
|
732
|
-
|
|
733
|
-
|
|
706
|
+
sumsubTncSigned,
|
|
707
|
+
idosTncSigned,
|
|
734
708
|
credentialReusabilityConsentGiven,
|
|
735
709
|
});
|
|
736
710
|
return;
|
|
@@ -742,12 +716,7 @@ class KycController extends base_controller_1.BaseController {
|
|
|
742
716
|
*/
|
|
743
717
|
clearSavedTerms() {
|
|
744
718
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
745
|
-
|
|
746
|
-
getDefaultKycVendorDisclaimersAccepted();
|
|
747
|
-
state.providerDisclaimersAccepted =
|
|
748
|
-
getDefaultKycProviderDisclaimersAccepted();
|
|
749
|
-
state.idosDisclaimersAccepted = null;
|
|
750
|
-
state.credentialReusabilityConsentGiven = null;
|
|
719
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
|
|
751
720
|
});
|
|
752
721
|
}
|
|
753
722
|
/**
|
|
@@ -761,7 +730,68 @@ class KycController extends base_controller_1.BaseController {
|
|
|
761
730
|
* @returns An object whose optional `reply` should be posted back.
|
|
762
731
|
*/
|
|
763
732
|
async handleFrameMessage(params) {
|
|
764
|
-
|
|
733
|
+
const payload = params.message;
|
|
734
|
+
if (!payload) {
|
|
735
|
+
return {};
|
|
736
|
+
}
|
|
737
|
+
if (payload.kind === 'handshake') {
|
|
738
|
+
const channelId = payload.meta?.channelId;
|
|
739
|
+
return { reply: { version: 2, meta: { channelId }, kind: 'ack' } };
|
|
740
|
+
}
|
|
741
|
+
if (payload.kind !== 'complete') {
|
|
742
|
+
return {};
|
|
743
|
+
}
|
|
744
|
+
const channelId = payload.meta?.channelId;
|
|
745
|
+
// Only honor a Check/Auth `complete` for the MoonPay frame the flow is
|
|
746
|
+
// currently waiting on. This drops stale or duplicate messages — e.g. a
|
|
747
|
+
// late post after `reset()` (phase `idle`), after the flow already
|
|
748
|
+
// advanced past this frame, or after a vendor switch — so they cannot
|
|
749
|
+
// resurrect tokens, rewind `phase`, or recapture `moonpayCustomerId` on a
|
|
750
|
+
// controller that has moved on. Frame messages are external input and,
|
|
751
|
+
// unlike the async steps, are not covered by the `#generation` guard.
|
|
752
|
+
let expectedPhase = null;
|
|
753
|
+
if (channelId === CHANNEL_CHECK) {
|
|
754
|
+
expectedPhase = 'check';
|
|
755
|
+
}
|
|
756
|
+
else if (channelId === CHANNEL_AUTH) {
|
|
757
|
+
expectedPhase = 'auth';
|
|
758
|
+
}
|
|
759
|
+
if (!expectedPhase ||
|
|
760
|
+
this.state.phase !== expectedPhase ||
|
|
761
|
+
this.state.activeVendor !== 'moonpay') {
|
|
762
|
+
return {};
|
|
763
|
+
}
|
|
764
|
+
const status = payload.payload?.status;
|
|
765
|
+
const credsEnvelope = payload.payload?.credentials;
|
|
766
|
+
const customerId = payload.payload?.customer?.id ?? null;
|
|
767
|
+
if (customerId) {
|
|
768
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
769
|
+
state.moonpayCustomerId = customerId;
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
if (!status) {
|
|
773
|
+
return {};
|
|
774
|
+
}
|
|
775
|
+
let accessToken;
|
|
776
|
+
let clientToken;
|
|
777
|
+
if (credsEnvelope) {
|
|
778
|
+
try {
|
|
779
|
+
const { credentials } = (0, crypto_js_1.decryptCredentials)(credsEnvelope, __classPrivateFieldGet(this, _KycController_keypair, "f").privateKey);
|
|
780
|
+
accessToken = credentials.accessToken;
|
|
781
|
+
clientToken = credentials.clientToken;
|
|
782
|
+
}
|
|
783
|
+
catch (error) {
|
|
784
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Failed to decrypt frame credentials: ${String(error)}`);
|
|
785
|
+
return {};
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
if (channelId === CHANNEL_CHECK) {
|
|
789
|
+
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_handleCheckOutcome).call(this, status, accessToken, clientToken);
|
|
790
|
+
return {};
|
|
791
|
+
}
|
|
792
|
+
// channelId === CHANNEL_AUTH, guaranteed by the expectedPhase guard above.
|
|
793
|
+
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_handleAuthOutcome).call(this, status, accessToken);
|
|
794
|
+
return {};
|
|
765
795
|
}
|
|
766
796
|
/**
|
|
767
797
|
* Builds the Check-frame URL, or `null` when no session exists yet.
|
|
@@ -769,7 +799,15 @@ class KycController extends base_controller_1.BaseController {
|
|
|
769
799
|
* @returns The Check-frame URL or `null`.
|
|
770
800
|
*/
|
|
771
801
|
buildCheckFrameUrl() {
|
|
772
|
-
|
|
802
|
+
if (this.state.activeVendor !== 'moonpay' || !this.state.sessionToken) {
|
|
803
|
+
return null;
|
|
804
|
+
}
|
|
805
|
+
const url = new URL(`${FRAMES_BASE_URL}/check-connection`);
|
|
806
|
+
url.searchParams.set('sessionToken', this.state.sessionToken);
|
|
807
|
+
url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_keypair, "f").publicKeyHex);
|
|
808
|
+
url.searchParams.set('channelId', CHANNEL_CHECK);
|
|
809
|
+
url.searchParams.set('skipKyc', 'true');
|
|
810
|
+
return url.toString();
|
|
773
811
|
}
|
|
774
812
|
/**
|
|
775
813
|
* Builds the Auth-frame URL, or `null` when no client token is available.
|
|
@@ -777,7 +815,14 @@ class KycController extends base_controller_1.BaseController {
|
|
|
777
815
|
* @returns The Auth-frame URL or `null`.
|
|
778
816
|
*/
|
|
779
817
|
buildAuthFrameUrl() {
|
|
780
|
-
|
|
818
|
+
if (this.state.activeVendor !== 'moonpay' || !__classPrivateFieldGet(this, _KycController_authClientToken, "f")) {
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
const url = new URL(`${FRAMES_BASE_URL}/auth`);
|
|
822
|
+
url.searchParams.set('clientToken', __classPrivateFieldGet(this, _KycController_authClientToken, "f"));
|
|
823
|
+
url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_keypair, "f").publicKeyHex);
|
|
824
|
+
url.searchParams.set('channelId', CHANNEL_AUTH);
|
|
825
|
+
return url.toString();
|
|
781
826
|
}
|
|
782
827
|
/**
|
|
783
828
|
* Builds the Reset-frame URL.
|
|
@@ -785,7 +830,9 @@ class KycController extends base_controller_1.BaseController {
|
|
|
785
830
|
* @returns The Reset-frame URL.
|
|
786
831
|
*/
|
|
787
832
|
buildResetFrameUrl() {
|
|
788
|
-
|
|
833
|
+
const url = new URL(`${FRAMES_BASE_URL}/reset`);
|
|
834
|
+
url.searchParams.set('channelId', CHANNEL_RESET);
|
|
835
|
+
return url.toString();
|
|
789
836
|
}
|
|
790
837
|
/**
|
|
791
838
|
* Checks whether KYC is required for a product and caches the result.
|
|
@@ -796,9 +843,9 @@ class KycController extends base_controller_1.BaseController {
|
|
|
796
843
|
* @returns Whether KYC is required.
|
|
797
844
|
*/
|
|
798
845
|
async checkKycRequired(params) {
|
|
799
|
-
const {
|
|
800
|
-
if (!
|
|
801
|
-
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing
|
|
846
|
+
const { accessToken } = this.state;
|
|
847
|
+
if (!accessToken) {
|
|
848
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing accessToken — repeat the authentication step.');
|
|
802
849
|
return false;
|
|
803
850
|
}
|
|
804
851
|
const country = params.country ?? this.state.geoCountry;
|
|
@@ -814,11 +861,7 @@ class KycController extends base_controller_1.BaseController {
|
|
|
814
861
|
state.statusMessage = 'Checking KYC status...';
|
|
815
862
|
});
|
|
816
863
|
try {
|
|
817
|
-
const { kycRequired } = await this.messenger.call('KycService:checkKycRequired', {
|
|
818
|
-
accessToken: moonpayAccessToken,
|
|
819
|
-
country,
|
|
820
|
-
capabilities: [{ product: params.product }],
|
|
821
|
-
});
|
|
864
|
+
const { kycRequired } = await this.messenger.call('KycService:checkKycRequired', { accessToken, country, capabilities: [{ product: params.product }] });
|
|
822
865
|
// The flow was reset while the check was in flight; discard the result
|
|
823
866
|
// rather than resurrecting a done/cached state on an idle controller.
|
|
824
867
|
const applied = __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
@@ -1103,11 +1146,13 @@ class KycController extends base_controller_1.BaseController {
|
|
|
1103
1146
|
state.phase = 'idle';
|
|
1104
1147
|
state.statusMessage = '';
|
|
1105
1148
|
state.error = null;
|
|
1106
|
-
state.
|
|
1107
|
-
state.
|
|
1149
|
+
state.disclaimers = [];
|
|
1150
|
+
state.disclaimersError = null;
|
|
1108
1151
|
state.sessionDisclaimers = null;
|
|
1109
1152
|
state.credentialReusabilityConsentGiven = null;
|
|
1110
|
-
|
|
1153
|
+
state.sessionToken = null;
|
|
1154
|
+
state.accessToken = null;
|
|
1155
|
+
state.moonpayCustomerId = null;
|
|
1111
1156
|
state.activeVendor = 'moonpay';
|
|
1112
1157
|
state.activeProduct = null;
|
|
1113
1158
|
state.sumsub = {
|
|
@@ -1135,7 +1180,7 @@ class KycController extends base_controller_1.BaseController {
|
|
|
1135
1180
|
}
|
|
1136
1181
|
}
|
|
1137
1182
|
exports.KycController = KycController;
|
|
1138
|
-
_KycController_sumsubLauncher = new WeakMap(),
|
|
1183
|
+
_KycController_sumsubLauncher = new WeakMap(), _KycController_keypair = 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() {
|
|
1139
1184
|
return {
|
|
1140
1185
|
get: async (path, entropySourceId) => this.messenger.call('UserStorageController:performGetStorage', path, entropySourceId),
|
|
1141
1186
|
set: async (path, value, entropySourceId) => this.messenger.call('UserStorageController:performSetStorage', path, value, entropySourceId),
|
|
@@ -1147,14 +1192,13 @@ _KycController_sumsubLauncher = new WeakMap(), _KycController_moonPayFrames = ne
|
|
|
1147
1192
|
* SumSub — skipping MoonPay Check/Auth frames.
|
|
1148
1193
|
*
|
|
1149
1194
|
* @param consents - T&C2 flags mapped onto the session disclaimer catalog.
|
|
1150
|
-
* @param consents.
|
|
1151
|
-
* @param consents.
|
|
1195
|
+
* @param consents.sumsubTncSigned - Whether Sumsub T&C were accepted.
|
|
1196
|
+
* @param consents.idosTncSigned - Whether idOS T&C were accepted.
|
|
1152
1197
|
* @param consents.credentialReusabilityConsentGiven - Whether credential
|
|
1153
1198
|
* reuse was accepted.
|
|
1154
1199
|
*/
|
|
1155
1200
|
async function _KycController_startConsentsSession(consents) {
|
|
1156
|
-
const { email } = this.state;
|
|
1157
|
-
const acceptedDisclaimerIds = (0, vendorDisclaimerAcceptance_js_1.ironDisclaimerIds)(this.state.vendorDisclaimersAccepted);
|
|
1201
|
+
const { email, acceptedDisclaimerIds } = this.state;
|
|
1158
1202
|
if (!email) {
|
|
1159
1203
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing email for consents session.');
|
|
1160
1204
|
return;
|
|
@@ -1172,7 +1216,7 @@ async function _KycController_startConsentsSession(consents) {
|
|
|
1172
1216
|
state.sumsub.result = null;
|
|
1173
1217
|
state.sumsub.sessionStatus = null;
|
|
1174
1218
|
// Consents-path vendors have no MoonPay session/access tokens.
|
|
1175
|
-
(
|
|
1219
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
|
|
1176
1220
|
});
|
|
1177
1221
|
try {
|
|
1178
1222
|
await this.messenger.call('KycService:submitVendorDisclaimers', {
|
|
@@ -1198,7 +1242,7 @@ async function _KycController_startConsentsSession(consents) {
|
|
|
1198
1242
|
await this.refreshKycStatus();
|
|
1199
1243
|
}
|
|
1200
1244
|
catch (statusError) {
|
|
1201
|
-
|
|
1245
|
+
console.error('KYC status refresh failed:', statusError);
|
|
1202
1246
|
}
|
|
1203
1247
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
1204
1248
|
state.phase = 'done';
|
|
@@ -1234,7 +1278,7 @@ async function _KycController_startConsentsSession(consents) {
|
|
|
1234
1278
|
await this.refreshKycStatus();
|
|
1235
1279
|
}
|
|
1236
1280
|
catch (statusError) {
|
|
1237
|
-
|
|
1281
|
+
console.error('KYC status refresh failed:', statusError);
|
|
1238
1282
|
}
|
|
1239
1283
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
1240
1284
|
if (state.phase !== 'error' && state.phase !== 'done') {
|
|
@@ -1262,7 +1306,7 @@ async function _KycController_startConsentsSession(consents) {
|
|
|
1262
1306
|
});
|
|
1263
1307
|
return;
|
|
1264
1308
|
}
|
|
1265
|
-
|
|
1309
|
+
console.error('Consents session failed:', error);
|
|
1266
1310
|
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
1267
1311
|
return;
|
|
1268
1312
|
}
|
|
@@ -1289,8 +1333,8 @@ async function _KycController_startConsentsSession(consents) {
|
|
|
1289
1333
|
*
|
|
1290
1334
|
* @param sessionId - The UKYC session id.
|
|
1291
1335
|
* @param consents - T&C2 flags mapped onto catalog documents.
|
|
1292
|
-
* @param consents.
|
|
1293
|
-
* @param consents.
|
|
1336
|
+
* @param consents.sumsubTncSigned - Whether Sumsub T&C were accepted.
|
|
1337
|
+
* @param consents.idosTncSigned - Whether idOS T&C were accepted.
|
|
1294
1338
|
* @param consents.credentialReusabilityConsentGiven - Whether credential
|
|
1295
1339
|
* reuse was accepted.
|
|
1296
1340
|
* @param generation - Flow generation captured by the caller.
|
|
@@ -1304,12 +1348,12 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
|
|
|
1304
1348
|
state.sessionDisclaimers = catalog;
|
|
1305
1349
|
state.statusMessage = 'Submitting consents...';
|
|
1306
1350
|
});
|
|
1307
|
-
if (isAcceptedCategoryEmpty(catalog.idOS, consents.
|
|
1308
|
-
isAcceptedCategoryEmpty(catalog.kycProvider, consents.
|
|
1351
|
+
if (isAcceptedCategoryEmpty(catalog.idOS, consents.idosTncSigned) ||
|
|
1352
|
+
isAcceptedCategoryEmpty(catalog.kycProvider, consents.sumsubTncSigned)) {
|
|
1309
1353
|
throw new Error('Session disclaimer catalog is missing documents for an accepted category.');
|
|
1310
1354
|
}
|
|
1311
|
-
const idOS =
|
|
1312
|
-
const kycProvider =
|
|
1355
|
+
const idOS = consentRecordsFromCatalog(catalog.idOS, consents.idosTncSigned);
|
|
1356
|
+
const kycProvider = consentRecordsFromCatalog(catalog.kycProvider, consents.sumsubTncSigned);
|
|
1313
1357
|
const reuseUnchanged = catalog.credentialReusabilityConsentGiven ===
|
|
1314
1358
|
consents.credentialReusabilityConsentGiven;
|
|
1315
1359
|
if (idOS.length === 0 && kycProvider.length === 0 && reuseUnchanged) {
|
|
@@ -1340,9 +1384,8 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
|
|
|
1340
1384
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1341
1385
|
state.sessionDisclaimers = latest;
|
|
1342
1386
|
});
|
|
1343
|
-
|
|
1344
|
-
const
|
|
1345
|
-
const stillMissingProvider = acceptedCategoryStillMissing(latest.kycProvider, consents.providerDisclaimersAccepted);
|
|
1387
|
+
const stillMissingIdos = acceptedCategoryStillMissing(latest.idOS, consents.idosTncSigned);
|
|
1388
|
+
const stillMissingProvider = acceptedCategoryStillMissing(latest.kycProvider, consents.sumsubTncSigned);
|
|
1346
1389
|
const stillMissingReuse = consents.credentialReusabilityConsentGiven &&
|
|
1347
1390
|
!latest.credentialReusabilityConsentGiven;
|
|
1348
1391
|
if (stillMissingIdos || stillMissingProvider || stillMissingReuse) {
|
|
@@ -1354,9 +1397,7 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
|
|
|
1354
1397
|
* Creates a vendor session from the currently stored terms + email.
|
|
1355
1398
|
*/
|
|
1356
1399
|
async function _KycController_createSession() {
|
|
1357
|
-
const { email } = this.state;
|
|
1358
|
-
const termsAcceptedAt = this.state.vendorDisclaimersAccepted.moonpay?.termsAcceptedAt;
|
|
1359
|
-
const acceptedDisclaimerIds = this.state.vendorDisclaimers.map((disclaimer) => disclaimer.id);
|
|
1400
|
+
const { email, termsAcceptedAt, acceptedDisclaimerIds } = this.state;
|
|
1360
1401
|
if (!email) {
|
|
1361
1402
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing email for session creation.');
|
|
1362
1403
|
return;
|
|
@@ -1371,7 +1412,7 @@ async function _KycController_createSession() {
|
|
|
1371
1412
|
// (or, on failure, invalid) session token, `buildAuthFrameUrl` cannot
|
|
1372
1413
|
// return a URL tied to an old client token, and `checkKycRequired` cannot
|
|
1373
1414
|
// run with an access token from an earlier authentication. The Check/Auth
|
|
1374
|
-
// frames re-populate these for the new session. Because `
|
|
1415
|
+
// frames re-populate these for the new session. Because `sessionToken` is
|
|
1375
1416
|
// cleared here and only re-set on success, a failed creation leaves it
|
|
1376
1417
|
// `null` rather than resurrecting the previous session.
|
|
1377
1418
|
// Capture the flow generation so a `reset()` landing while the create
|
|
@@ -1379,24 +1420,24 @@ async function _KycController_createSession() {
|
|
|
1379
1420
|
// the now-idle controller (failure). The synchronous update below runs
|
|
1380
1421
|
// before any `await`, so it needs no guard.
|
|
1381
1422
|
const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
|
|
1382
|
-
|
|
1423
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
|
|
1383
1424
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1384
1425
|
state.error = null;
|
|
1385
1426
|
state.phase = 'session';
|
|
1386
1427
|
state.statusMessage = 'Creating session...';
|
|
1387
|
-
state.
|
|
1388
|
-
state.
|
|
1428
|
+
state.sessionToken = null;
|
|
1429
|
+
state.accessToken = null;
|
|
1389
1430
|
});
|
|
1390
1431
|
try {
|
|
1391
1432
|
const { sessionToken } = await this.messenger.call('KycService:createSession', { email, termsAcceptedAt, disclaimerIds: acceptedDisclaimerIds });
|
|
1392
1433
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
|
|
1393
|
-
state.
|
|
1434
|
+
state.sessionToken = sessionToken;
|
|
1394
1435
|
state.phase = 'check';
|
|
1395
1436
|
state.statusMessage = 'Authenticating via Check frame...';
|
|
1396
1437
|
});
|
|
1397
1438
|
}
|
|
1398
1439
|
catch (error) {
|
|
1399
|
-
|
|
1440
|
+
console.error('Session creation failed:', error);
|
|
1400
1441
|
// A reset() superseded this flow while the request was in flight; leave
|
|
1401
1442
|
// the idle controller alone rather than forcing it back to `terms`.
|
|
1402
1443
|
if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
|
|
@@ -1416,13 +1457,82 @@ async function _KycController_createSession() {
|
|
|
1416
1457
|
});
|
|
1417
1458
|
await this.loadDisclaimers();
|
|
1418
1459
|
}
|
|
1419
|
-
}, _KycController_clearAcceptedTerms = function _KycController_clearAcceptedTerms(state
|
|
1420
|
-
|
|
1421
|
-
state.
|
|
1422
|
-
state.
|
|
1423
|
-
|
|
1424
|
-
state.
|
|
1460
|
+
}, _KycController_clearAcceptedTerms = function _KycController_clearAcceptedTerms(state) {
|
|
1461
|
+
state.termsAcceptedAt = null;
|
|
1462
|
+
state.acceptedDisclaimerIds = [];
|
|
1463
|
+
state.termsAcceptedVendor = null;
|
|
1464
|
+
state.sumsubTncAccepted = null;
|
|
1465
|
+
state.idosTncAccepted = null;
|
|
1425
1466
|
state.credentialReusabilityConsentGiven = null;
|
|
1467
|
+
}, _KycController_clearMoonPaySession = function _KycController_clearMoonPaySession(state) {
|
|
1468
|
+
state.moonpayCustomerId = null;
|
|
1469
|
+
state.sessionToken = null;
|
|
1470
|
+
state.accessToken = null;
|
|
1471
|
+
}, _KycController_dropTermsUnlessForVendor = function _KycController_dropTermsUnlessForVendor(vendor) {
|
|
1472
|
+
if (__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_hasTermsForVendor).call(this, vendor)) {
|
|
1473
|
+
return;
|
|
1474
|
+
}
|
|
1475
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1476
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
|
|
1477
|
+
});
|
|
1478
|
+
}, _KycController_hasTermsForVendor = function _KycController_hasTermsForVendor(vendor) {
|
|
1479
|
+
if (this.state.termsAcceptedVendor === null) {
|
|
1480
|
+
return false;
|
|
1481
|
+
}
|
|
1482
|
+
return this.state.termsAcceptedVendor === vendor;
|
|
1483
|
+
}, _KycController_handleCheckOutcome =
|
|
1484
|
+
/**
|
|
1485
|
+
* Applies a Check-frame outcome.
|
|
1486
|
+
*
|
|
1487
|
+
* @param status - The frame status.
|
|
1488
|
+
* @param accessToken - The decrypted access token, if any.
|
|
1489
|
+
* @param clientToken - The decrypted client token, if any.
|
|
1490
|
+
*/
|
|
1491
|
+
async function _KycController_handleCheckOutcome(status, accessToken, clientToken) {
|
|
1492
|
+
if (status === 'active' && accessToken) {
|
|
1493
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1494
|
+
state.accessToken = accessToken;
|
|
1495
|
+
state.phase = 'form';
|
|
1496
|
+
state.statusMessage = 'Already authenticated. Review to submit.';
|
|
1497
|
+
});
|
|
1498
|
+
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this);
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
if (status === 'connectionRequired' && clientToken) {
|
|
1502
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, clientToken, "f");
|
|
1503
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1504
|
+
state.phase = 'auth';
|
|
1505
|
+
state.statusMessage = 'Verify your email via OTP in the Auth frame.';
|
|
1506
|
+
});
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
if (status === 'termsAcceptanceRequired') {
|
|
1510
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this);
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Check frame returned status: ${status}`);
|
|
1514
|
+
}, _KycController_handleAuthOutcome =
|
|
1515
|
+
/**
|
|
1516
|
+
* Applies an Auth-frame outcome.
|
|
1517
|
+
*
|
|
1518
|
+
* @param status - The frame status.
|
|
1519
|
+
* @param accessToken - The decrypted access token, if any.
|
|
1520
|
+
*/
|
|
1521
|
+
async function _KycController_handleAuthOutcome(status, accessToken) {
|
|
1522
|
+
if (status === 'active' && accessToken) {
|
|
1523
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
|
|
1524
|
+
state.accessToken = accessToken;
|
|
1525
|
+
state.phase = 'form';
|
|
1526
|
+
state.statusMessage = 'Authenticated. Review to submit.';
|
|
1527
|
+
});
|
|
1528
|
+
await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this);
|
|
1529
|
+
return;
|
|
1530
|
+
}
|
|
1531
|
+
if (status === 'termsAcceptanceRequired') {
|
|
1532
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this);
|
|
1533
|
+
return;
|
|
1534
|
+
}
|
|
1535
|
+
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Auth frame returned status: ${status}`);
|
|
1426
1536
|
}, _KycController_continueAfterAuthentication =
|
|
1427
1537
|
/**
|
|
1428
1538
|
* Continues the flow once authentication has completed (phase `form`).
|
|
@@ -1474,7 +1584,7 @@ async function _KycController_continueAfterAuthentication() {
|
|
|
1474
1584
|
return {
|
|
1475
1585
|
vendor: 'moonpay',
|
|
1476
1586
|
vendorMetadata: {
|
|
1477
|
-
moonPayAccessToken: this.state.
|
|
1587
|
+
moonPayAccessToken: this.state.accessToken,
|
|
1478
1588
|
moonPayUserId: this.state.moonpayCustomerId,
|
|
1479
1589
|
},
|
|
1480
1590
|
};
|
|
@@ -1542,8 +1652,7 @@ async function _KycController_createUkycSession(generation) {
|
|
|
1542
1652
|
// authorizes later storage reads without granting write or delete access.
|
|
1543
1653
|
const ukycCapabilityToken = (0, storageAccessToken_js_1.signStorageAccessToken)({
|
|
1544
1654
|
material: clientMaterial,
|
|
1545
|
-
|
|
1546
|
-
operations: ['read', 'write'],
|
|
1655
|
+
operations: ['read'],
|
|
1547
1656
|
expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),
|
|
1548
1657
|
});
|
|
1549
1658
|
const wrappedUkycCapabilityToken = (0, wrapEncryptionKey_js_1.wrapEncryptionKey)(sessionClientPrivateKey, capabilityTokenSchema.serverPublicKey.x, (0, utils_1.stringToBytes)((0, storageAccessToken_js_1.encodeStorageAccessTokenForHeader)(ukycCapabilityToken)));
|
|
@@ -1730,7 +1839,7 @@ async function _KycController_pollSessionStatusOnce(sessionId, token) {
|
|
|
1730
1839
|
__classPrivateFieldSet(this, _KycController_pollTimer, null, "f");
|
|
1731
1840
|
}
|
|
1732
1841
|
}, _KycController_cancelPendingSession = function _KycController_cancelPendingSession() {
|
|
1733
|
-
|
|
1842
|
+
__classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
|
|
1734
1843
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopPolling).call(this);
|
|
1735
1844
|
__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopUserStatusPolling).call(this);
|
|
1736
1845
|
__classPrivateFieldSet(this, _KycController_generation, __classPrivateFieldGet(this, _KycController_generation, "f") + 1, "f");
|