@metamask-previews/seedless-onboarding-controller 2.5.0-preview-3f5f144a → 2.5.0-preview-848c8e7d
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/dist/SeedlessOnboardingController.cjs +119 -112
- package/dist/SeedlessOnboardingController.cjs.map +1 -1
- package/dist/SeedlessOnboardingController.d.cts.map +1 -1
- package/dist/SeedlessOnboardingController.d.mts.map +1 -1
- package/dist/SeedlessOnboardingController.mjs +121 -114
- package/dist/SeedlessOnboardingController.mjs.map +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +1 -1
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +1 -1
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +1 -1
- package/dist/constants.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +30 -36
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +30 -36
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils.cjs +28 -1
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +15 -0
- package/dist/utils.d.cts.map +1 -1
- package/dist/utils.d.mts +15 -0
- package/dist/utils.d.mts.map +1 -1
- package/dist/utils.mjs +26 -1
- package/dist/utils.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -9,11 +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 _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_passwordOutdatedCacheTTL, _SeedlessOnboardingController_submitGlobalPassword, _SeedlessOnboardingController_getAccessToken, _SeedlessOnboardingController_setUnlocked, _SeedlessOnboardingController_persistOprfKey, _SeedlessOnboardingController_persistAuthPubKey, _SeedlessOnboardingController_storeKeyringEncryptionKey, _SeedlessOnboardingController_loadKeyringEncryptionKey, _SeedlessOnboardingController_loadSeedlessEncryptionKey, _SeedlessOnboardingController_recoverAuthPubKey, _SeedlessOnboardingController_recoverEncKey, _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore, _SeedlessOnboardingController_changeEncryptionKey, _SeedlessOnboardingController_encryptAndStoreSecretData, _SeedlessOnboardingController_unlockVaultAndGetVaultData, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState, _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata,
|
|
12
|
+
var _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_passwordOutdatedCacheTTL, _SeedlessOnboardingController_submitGlobalPassword, _SeedlessOnboardingController_getAccessToken, _SeedlessOnboardingController_setUnlocked, _SeedlessOnboardingController_persistOprfKey, _SeedlessOnboardingController_persistAuthPubKey, _SeedlessOnboardingController_storeKeyringEncryptionKey, _SeedlessOnboardingController_loadKeyringEncryptionKey, _SeedlessOnboardingController_loadSeedlessEncryptionKey, _SeedlessOnboardingController_recoverAuthPubKey, _SeedlessOnboardingController_recoverEncKey, _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore, _SeedlessOnboardingController_changeEncryptionKey, _SeedlessOnboardingController_encryptAndStoreSecretData, _SeedlessOnboardingController_unlockVaultAndGetVaultData, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState, _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata, _SeedlessOnboardingController_updateVault, _SeedlessOnboardingController_withControllerLock, _SeedlessOnboardingController_withVaultLock, _SeedlessOnboardingController_parseVaultData, _SeedlessOnboardingController_assertIsUnlocked, _SeedlessOnboardingController_assertIsAuthenticatedUser, _SeedlessOnboardingController_assertIsSRPBackedUpUser, _SeedlessOnboardingController_assertPasswordInSync, _SeedlessOnboardingController_resetPasswordOutdatedCache, _SeedlessOnboardingController_isTokenExpiredError, _SeedlessOnboardingController_isMaxKeyChainLengthError, _SeedlessOnboardingController_executeWithTokenRefresh;
|
|
13
13
|
import { keccak256AndHexify } from "@metamask/auth-network-utils";
|
|
14
14
|
import { BaseController } from "@metamask/base-controller";
|
|
15
15
|
import { ToprfSecureBackup, TOPRFErrorCode, TOPRFError } from "@metamask/toprf-secure-backup";
|
|
16
|
-
import { base64ToBytes, bytesToBase64
|
|
16
|
+
import { base64ToBytes, bytesToBase64 } from "@metamask/utils";
|
|
17
17
|
import { gcm } from "@noble/ciphers/aes";
|
|
18
18
|
import { bytesToUtf8, utf8ToBytes } from "@noble/ciphers/utils";
|
|
19
19
|
import { managedNonce } from "@noble/ciphers/webcrypto";
|
|
@@ -24,7 +24,7 @@ import { controllerName, PASSWORD_OUTDATED_CACHE_TTL_MS, SecretType, SeedlessOnb
|
|
|
24
24
|
import { PasswordSyncError, RecoveryError } from "./errors.mjs";
|
|
25
25
|
import { projectLogger, createModuleLogger } from "./logger.mjs";
|
|
26
26
|
import { SecretMetadata } from "./SecretMetadata.mjs";
|
|
27
|
-
import { decodeJWTToken, decodeNodeAuthToken } from "./utils.mjs";
|
|
27
|
+
import { decodeJWTToken, decodeNodeAuthToken, deserializAuthKeyPair, serializeAuthKeyPair } from "./utils.mjs";
|
|
28
28
|
const log = createModuleLogger(projectLogger, controllerName);
|
|
29
29
|
/**
|
|
30
30
|
* Get the default state for the Seedless Onboarding Controller.
|
|
@@ -80,10 +80,6 @@ const seedlessOnboardingMetadata = {
|
|
|
80
80
|
persist: false,
|
|
81
81
|
anonymous: true,
|
|
82
82
|
},
|
|
83
|
-
vaultEncryptionSalt: {
|
|
84
|
-
persist: false,
|
|
85
|
-
anonymous: true,
|
|
86
|
-
},
|
|
87
83
|
authPubKey: {
|
|
88
84
|
persist: true,
|
|
89
85
|
anonymous: true,
|
|
@@ -119,6 +115,18 @@ const seedlessOnboardingMetadata = {
|
|
|
119
115
|
persist: true,
|
|
120
116
|
anonymous: true,
|
|
121
117
|
},
|
|
118
|
+
toprfEncryptionKey: {
|
|
119
|
+
persist: false,
|
|
120
|
+
anonymous: true,
|
|
121
|
+
},
|
|
122
|
+
toprfPwEncryptionKey: {
|
|
123
|
+
persist: false,
|
|
124
|
+
anonymous: true,
|
|
125
|
+
},
|
|
126
|
+
toprfAuthKeyPair: {
|
|
127
|
+
persist: false,
|
|
128
|
+
anonymous: true,
|
|
129
|
+
},
|
|
122
130
|
};
|
|
123
131
|
export class SeedlessOnboardingController extends BaseController {
|
|
124
132
|
/**
|
|
@@ -292,7 +300,7 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
292
300
|
// to have an account but with no associated data.
|
|
293
301
|
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_persistOprfKey).call(this, oprfKey, authKeyPair.pk);
|
|
294
302
|
// create a new vault with the resulting authentication data
|
|
295
|
-
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
303
|
+
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
|
|
296
304
|
password,
|
|
297
305
|
rawToprfEncryptionKey: encKey,
|
|
298
306
|
rawToprfPwEncryptionKey: pwEncKey,
|
|
@@ -313,20 +321,22 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
313
321
|
*/
|
|
314
322
|
async addNewSecretData(data, type, options) {
|
|
315
323
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
|
|
316
|
-
|
|
324
|
+
// assert that the controller is unlocked before adding new secret data
|
|
325
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
|
|
326
|
+
// get the TOPRF encryption key and authentication key pair from the state
|
|
327
|
+
const { toprfEncryptionKey, toprfAuthKeyPair } = this.state;
|
|
328
|
+
// assert that the password is in sync with the encryption key
|
|
317
329
|
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertPasswordInSync).call(this, {
|
|
318
330
|
skipCache: true,
|
|
319
331
|
skipLock: true, // skip lock since we already have the lock
|
|
320
332
|
});
|
|
321
333
|
const performBackup = async () => {
|
|
322
|
-
// verify the password and unlock the vault
|
|
323
|
-
const { toprfEncryptionKey, toprfAuthKeyPair } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this);
|
|
324
334
|
// encrypt and store the secret data
|
|
325
335
|
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_encryptAndStoreSecretData).call(this, {
|
|
326
336
|
data,
|
|
327
337
|
type,
|
|
328
|
-
encKey: toprfEncryptionKey,
|
|
329
|
-
authKeyPair: toprfAuthKeyPair,
|
|
338
|
+
encKey: base64ToBytes(toprfEncryptionKey),
|
|
339
|
+
authKeyPair: deserializAuthKeyPair(toprfAuthKeyPair),
|
|
330
340
|
options,
|
|
331
341
|
});
|
|
332
342
|
};
|
|
@@ -355,18 +365,17 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
355
365
|
authKeyPair = recoverEncKeyResult.authKeyPair;
|
|
356
366
|
}
|
|
357
367
|
else {
|
|
358
|
-
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
authKeyPair = keysFromVault.toprfAuthKeyPair;
|
|
368
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
|
|
369
|
+
const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair } = this.state;
|
|
370
|
+
encKey = base64ToBytes(toprfEncryptionKey);
|
|
371
|
+
pwEncKey = base64ToBytes(toprfPwEncryptionKey);
|
|
372
|
+
authKeyPair = deserializAuthKeyPair(toprfAuthKeyPair);
|
|
364
373
|
}
|
|
365
374
|
const performFetch = async () => {
|
|
366
375
|
const secrets = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_fetchAllSecretDataFromMetadataStore).call(this, encKey, authKeyPair);
|
|
367
376
|
if (password) {
|
|
368
377
|
// if password is provided, we need to create a new vault with the auth data. (supposedly the user is trying to rehydrate the wallet)
|
|
369
|
-
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
378
|
+
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
|
|
370
379
|
password,
|
|
371
380
|
rawToprfEncryptionKey: encKey,
|
|
372
381
|
rawToprfPwEncryptionKey: pwEncKey,
|
|
@@ -389,7 +398,8 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
389
398
|
*/
|
|
390
399
|
async changePassword(newPassword, oldPassword) {
|
|
391
400
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
|
|
392
|
-
|
|
401
|
+
// assert that the controller is unlocked before changing the password
|
|
402
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
|
|
393
403
|
// verify the old password of the encrypted vault
|
|
394
404
|
await this.verifyVaultPassword(oldPassword, {
|
|
395
405
|
skipLock: true, // skip lock since we already have the lock
|
|
@@ -411,7 +421,7 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
411
421
|
latestKeyIndex,
|
|
412
422
|
});
|
|
413
423
|
// update and encrypt the vault with new password
|
|
414
|
-
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
424
|
+
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
|
|
415
425
|
password: newPassword,
|
|
416
426
|
rawToprfEncryptionKey: newEncKey,
|
|
417
427
|
rawToprfPwEncryptionKey: newPwEncKey,
|
|
@@ -440,7 +450,7 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
440
450
|
* @param secretData.data - The secret data to update the backup metadata state.
|
|
441
451
|
*/
|
|
442
452
|
updateBackupMetadataState(secretData) {
|
|
443
|
-
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
|
|
453
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
|
|
444
454
|
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata).call(this, secretData);
|
|
445
455
|
}
|
|
446
456
|
/**
|
|
@@ -489,7 +499,7 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
489
499
|
*/
|
|
490
500
|
async submitPassword(password) {
|
|
491
501
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
|
|
492
|
-
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, password);
|
|
502
|
+
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, { password });
|
|
493
503
|
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
|
|
494
504
|
});
|
|
495
505
|
}
|
|
@@ -501,7 +511,9 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
501
511
|
setLocked() {
|
|
502
512
|
this.update((state) => {
|
|
503
513
|
delete state.vaultEncryptionKey;
|
|
504
|
-
delete state.
|
|
514
|
+
delete state.toprfEncryptionKey;
|
|
515
|
+
delete state.toprfPwEncryptionKey;
|
|
516
|
+
delete state.toprfAuthKeyPair;
|
|
505
517
|
delete state.revokeToken;
|
|
506
518
|
delete state.accessToken;
|
|
507
519
|
});
|
|
@@ -518,12 +530,12 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
518
530
|
*/
|
|
519
531
|
async syncLatestGlobalPassword({ globalPassword, }) {
|
|
520
532
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
|
|
521
|
-
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this);
|
|
533
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
|
|
522
534
|
const doSyncPassword = async () => {
|
|
523
535
|
// update vault with latest globalPassword
|
|
524
536
|
const { encKey, pwEncKey, authKeyPair } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, globalPassword);
|
|
525
537
|
// update and encrypt the vault with new password
|
|
526
|
-
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
538
|
+
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
|
|
527
539
|
password: globalPassword,
|
|
528
540
|
rawToprfEncryptionKey: encKey,
|
|
529
541
|
rawToprfPwEncryptionKey: pwEncKey,
|
|
@@ -624,7 +636,9 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
624
636
|
* @param keyringEncryptionKey - The keyring encryption key.
|
|
625
637
|
*/
|
|
626
638
|
async storeKeyringEncryptionKey(keyringEncryptionKey) {
|
|
627
|
-
|
|
639
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
|
|
640
|
+
const { toprfPwEncryptionKey } = this.state;
|
|
641
|
+
const encKey = base64ToBytes(toprfPwEncryptionKey);
|
|
628
642
|
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_storeKeyringEncryptionKey).call(this, encKey, keyringEncryptionKey);
|
|
629
643
|
}
|
|
630
644
|
/**
|
|
@@ -634,7 +648,9 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
634
648
|
* @returns The keyring encryption key.
|
|
635
649
|
*/
|
|
636
650
|
async loadKeyringEncryptionKey() {
|
|
637
|
-
|
|
651
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
|
|
652
|
+
const { toprfPwEncryptionKey } = this.state;
|
|
653
|
+
const encKey = base64ToBytes(toprfPwEncryptionKey);
|
|
638
654
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_loadKeyringEncryptionKey).call(this, encKey);
|
|
639
655
|
}
|
|
640
656
|
/**
|
|
@@ -683,7 +699,10 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
683
699
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
|
|
684
700
|
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
|
|
685
701
|
const { vaultEncryptionKey } = this.state;
|
|
686
|
-
const { toprfEncryptionKey: rawToprfEncryptionKey, toprfPwEncryptionKey: rawToprfPwEncryptionKey, toprfAuthKeyPair: rawToprfAuthKeyPair, revokeToken, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this,
|
|
702
|
+
const { toprfEncryptionKey: rawToprfEncryptionKey, toprfPwEncryptionKey: rawToprfPwEncryptionKey, toprfAuthKeyPair: rawToprfAuthKeyPair, revokeToken, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, {
|
|
703
|
+
password,
|
|
704
|
+
encryptionKey: vaultEncryptionKey,
|
|
705
|
+
});
|
|
687
706
|
if (!revokeToken) {
|
|
688
707
|
throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidRevokeToken);
|
|
689
708
|
}
|
|
@@ -697,7 +716,7 @@ export class SeedlessOnboardingController extends BaseController {
|
|
|
697
716
|
// set new refresh token to persist in state
|
|
698
717
|
state.refreshToken = newRefreshToken;
|
|
699
718
|
});
|
|
700
|
-
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m",
|
|
719
|
+
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
|
|
701
720
|
password,
|
|
702
721
|
rawToprfEncryptionKey,
|
|
703
722
|
rawToprfPwEncryptionKey,
|
|
@@ -784,7 +803,9 @@ async function _SeedlessOnboardingController_submitGlobalPassword({ targetAuthPu
|
|
|
784
803
|
const { pwEncKey } = res;
|
|
785
804
|
const vaultKey = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_loadSeedlessEncryptionKey).call(this, pwEncKey);
|
|
786
805
|
// Unlock the controller
|
|
787
|
-
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this,
|
|
806
|
+
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, {
|
|
807
|
+
encryptionKey: vaultKey,
|
|
808
|
+
});
|
|
788
809
|
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
|
|
789
810
|
}
|
|
790
811
|
catch (error) {
|
|
@@ -816,7 +837,10 @@ async function _SeedlessOnboardingController_getAccessToken(password) {
|
|
|
816
837
|
if (!vault) {
|
|
817
838
|
throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidAccessToken);
|
|
818
839
|
}
|
|
819
|
-
const { accessToken: accessTokenFromVault } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this,
|
|
840
|
+
const { accessToken: accessTokenFromVault } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetVaultData).call(this, {
|
|
841
|
+
password,
|
|
842
|
+
skipVaultMutexLock: true,
|
|
843
|
+
});
|
|
820
844
|
return accessTokenFromVault;
|
|
821
845
|
}, _SeedlessOnboardingController_setUnlocked = function _SeedlessOnboardingController_setUnlocked() {
|
|
822
846
|
__classPrivateFieldSet(this, _SeedlessOnboardingController_isUnlocked, true, "f");
|
|
@@ -935,7 +959,6 @@ async function _SeedlessOnboardingController_recoverEncKey(password) {
|
|
|
935
959
|
});
|
|
936
960
|
}
|
|
937
961
|
catch (error) {
|
|
938
|
-
log('Error fetching secret data', error);
|
|
939
962
|
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isTokenExpiredError).call(this, error)) {
|
|
940
963
|
throw error;
|
|
941
964
|
}
|
|
@@ -978,11 +1001,12 @@ async function _SeedlessOnboardingController_changeEncryptionKey({ oldPassword,
|
|
|
978
1001
|
} = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, oldPassword));
|
|
979
1002
|
}
|
|
980
1003
|
else {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1004
|
+
// get the TOPRF encryption key and authentication key pair from the state
|
|
1005
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsUnlocked).call(this, this.state);
|
|
1006
|
+
const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair } = this.state;
|
|
1007
|
+
encKey = base64ToBytes(toprfEncryptionKey);
|
|
1008
|
+
pwEncKey = base64ToBytes(toprfPwEncryptionKey);
|
|
1009
|
+
authKeyPair = deserializAuthKeyPair(toprfAuthKeyPair);
|
|
986
1010
|
}
|
|
987
1011
|
const result = await this.toprfClient.changeEncKey({
|
|
988
1012
|
nodeAuthTokens: this.state.nodeAuthTokens,
|
|
@@ -1048,11 +1072,15 @@ async function _SeedlessOnboardingController_encryptAndStoreSecretData(params) {
|
|
|
1048
1072
|
}
|
|
1049
1073
|
}, _SeedlessOnboardingController_unlockVaultAndGetVaultData =
|
|
1050
1074
|
/**
|
|
1051
|
-
* Unlocks the encrypted vault using the provided password and returns the decrypted vault data.
|
|
1075
|
+
* Unlocks the encrypted vault using the provided password or encryption key and returns the decrypted vault data.
|
|
1052
1076
|
* This method ensures thread-safety by using a mutex lock when accessing the vault.
|
|
1053
1077
|
*
|
|
1054
|
-
*
|
|
1055
|
-
*
|
|
1078
|
+
* Successfully unlocking the vault will update the controller state with the decrypted vault data.
|
|
1079
|
+
*
|
|
1080
|
+
* @param params - The parameters for unlocking the vault.
|
|
1081
|
+
* @param params.password - The optional password to unlock the vault.
|
|
1082
|
+
* @param params.encryptionKey - The optional encryption key to unlock the vault.
|
|
1083
|
+
* @param params.skipVaultMutexLock - Whether to skip the vault mutex lock.
|
|
1056
1084
|
* @returns A promise that resolves to an object containing:
|
|
1057
1085
|
* - toprfEncryptionKey: The decrypted TOPRF encryption key
|
|
1058
1086
|
* - toprfAuthKeyPair: The decrypted TOPRF authentication key pair
|
|
@@ -1064,44 +1092,40 @@ async function _SeedlessOnboardingController_encryptAndStoreSecretData(params) {
|
|
|
1064
1092
|
* - The password is incorrect (from encryptor.decrypt)
|
|
1065
1093
|
* - The decrypted vault data is malformed
|
|
1066
1094
|
*/
|
|
1067
|
-
async function _SeedlessOnboardingController_unlockVaultAndGetVaultData(
|
|
1068
|
-
|
|
1095
|
+
async function _SeedlessOnboardingController_unlockVaultAndGetVaultData(params) {
|
|
1096
|
+
const doUnlockVaultAndGetVaultData = async () => {
|
|
1069
1097
|
let { vaultEncryptionKey } = this.state;
|
|
1070
|
-
const { vault: encryptedVault
|
|
1098
|
+
const { vault: encryptedVault } = this.state;
|
|
1071
1099
|
if (!encryptedVault) {
|
|
1072
1100
|
throw new Error(SeedlessOnboardingControllerErrorMessage.VaultError);
|
|
1073
1101
|
}
|
|
1074
|
-
if (encryptionKey) {
|
|
1075
|
-
vaultEncryptionKey = encryptionKey;
|
|
1102
|
+
if (params?.encryptionKey) {
|
|
1103
|
+
vaultEncryptionKey = params.encryptionKey;
|
|
1076
1104
|
}
|
|
1077
1105
|
let decryptedVaultData;
|
|
1078
1106
|
const updatedState = {};
|
|
1079
|
-
if (password) {
|
|
1080
|
-
assertIsValidPassword(password);
|
|
1107
|
+
if (params?.password) {
|
|
1108
|
+
assertIsValidPassword(params.password);
|
|
1081
1109
|
// Note that vault decryption using the password is a very costly operation as it involves deriving the encryption key
|
|
1082
1110
|
// from the password using an intentionally slow key derivation function.
|
|
1083
1111
|
// We should make sure that we only call it very intentionally.
|
|
1084
|
-
const result = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").decryptWithDetail(password, encryptedVault);
|
|
1112
|
+
const result = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").decryptWithDetail(params.password, encryptedVault);
|
|
1085
1113
|
decryptedVaultData = result.vault;
|
|
1086
1114
|
updatedState.vaultEncryptionKey = result.exportedKeyString;
|
|
1087
|
-
updatedState.vaultEncryptionSalt = result.salt;
|
|
1088
1115
|
}
|
|
1089
1116
|
else {
|
|
1090
1117
|
assertIsVaultEncryptionKeyDefined(vaultEncryptionKey);
|
|
1091
1118
|
const parsedEncryptedVault = JSON.parse(encryptedVault);
|
|
1092
|
-
if (vaultEncryptionSalt &&
|
|
1093
|
-
vaultEncryptionSalt !== parsedEncryptedVault.salt) {
|
|
1094
|
-
throw new Error(SeedlessOnboardingControllerErrorMessage.ExpiredCredentials);
|
|
1095
|
-
}
|
|
1096
1119
|
const key = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").importKey(vaultEncryptionKey);
|
|
1097
1120
|
decryptedVaultData = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1098
1121
|
updatedState.vaultEncryptionKey = vaultEncryptionKey;
|
|
1099
|
-
updatedState.vaultEncryptionSalt = vaultEncryptionSalt;
|
|
1100
1122
|
}
|
|
1101
1123
|
const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair, revokeToken, accessToken, } = __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_parseVaultData).call(this, decryptedVaultData);
|
|
1102
1124
|
this.update((state) => {
|
|
1103
1125
|
state.vaultEncryptionKey = updatedState.vaultEncryptionKey;
|
|
1104
|
-
state.
|
|
1126
|
+
state.toprfEncryptionKey = bytesToBase64(toprfEncryptionKey);
|
|
1127
|
+
state.toprfPwEncryptionKey = bytesToBase64(toprfPwEncryptionKey);
|
|
1128
|
+
state.toprfAuthKeyPair = serializeAuthKeyPair(toprfAuthKeyPair);
|
|
1105
1129
|
state.revokeToken = revokeToken;
|
|
1106
1130
|
state.accessToken = accessToken;
|
|
1107
1131
|
});
|
|
@@ -1112,7 +1136,10 @@ async function _SeedlessOnboardingController_unlockVaultAndGetVaultData(password
|
|
|
1112
1136
|
revokeToken,
|
|
1113
1137
|
accessToken,
|
|
1114
1138
|
};
|
|
1115
|
-
}
|
|
1139
|
+
};
|
|
1140
|
+
return params?.skipVaultMutexLock
|
|
1141
|
+
? doUnlockVaultAndGetVaultData()
|
|
1142
|
+
: __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withVaultLock).call(this, doUnlockVaultAndGetVaultData);
|
|
1116
1143
|
}, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState =
|
|
1117
1144
|
/**
|
|
1118
1145
|
* Executes a callback function that creates or restores secret data and persists their hashes in the controller state.
|
|
@@ -1169,65 +1196,54 @@ async function _SeedlessOnboardingController_withPersistedSecretMetadataBackupsS
|
|
|
1169
1196
|
];
|
|
1170
1197
|
});
|
|
1171
1198
|
}
|
|
1172
|
-
}, _SeedlessOnboardingController_createNewVaultWithAuthData =
|
|
1173
|
-
/**
|
|
1174
|
-
* Create a new vault with the given authentication data.
|
|
1175
|
-
*
|
|
1176
|
-
* Serialize the authentication and key data which will be stored in the vault.
|
|
1177
|
-
*
|
|
1178
|
-
* @param params - The parameters for creating a new vault.
|
|
1179
|
-
* @param params.password - The password to encrypt the vault.
|
|
1180
|
-
* @param params.rawToprfEncryptionKey - The encryption key to encrypt the vault.
|
|
1181
|
-
* @param params.rawToprfPwEncryptionKey - The encryption key to encrypt the password.
|
|
1182
|
-
* @param params.rawToprfAuthKeyPair - The authentication key pair to encrypt the vault.
|
|
1183
|
-
*/
|
|
1184
|
-
async function _SeedlessOnboardingController_createNewVaultWithAuthData({ password, rawToprfEncryptionKey, rawToprfPwEncryptionKey, rawToprfAuthKeyPair, }) {
|
|
1185
|
-
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
|
|
1186
|
-
const accessToken = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_getAccessToken).call(this, password);
|
|
1187
|
-
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
|
|
1188
|
-
const { toprfEncryptionKey, toprfPwEncryptionKey, toprfAuthKeyPair } = __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_serializeKeyData).call(this, rawToprfEncryptionKey, rawToprfPwEncryptionKey, rawToprfAuthKeyPair);
|
|
1189
|
-
const serializedVaultData = JSON.stringify({
|
|
1190
|
-
toprfEncryptionKey,
|
|
1191
|
-
toprfPwEncryptionKey,
|
|
1192
|
-
toprfAuthKeyPair,
|
|
1193
|
-
revokeToken: this.state.revokeToken,
|
|
1194
|
-
accessToken,
|
|
1195
|
-
});
|
|
1196
|
-
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_updateVault).call(this, {
|
|
1197
|
-
password,
|
|
1198
|
-
serializedVaultData,
|
|
1199
|
-
pwEncKey: rawToprfPwEncryptionKey,
|
|
1200
|
-
});
|
|
1201
|
-
// update the authPubKey in the state
|
|
1202
|
-
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_persistAuthPubKey).call(this, {
|
|
1203
|
-
authPubKey: rawToprfAuthKeyPair.pk,
|
|
1204
|
-
});
|
|
1205
1199
|
}, _SeedlessOnboardingController_updateVault =
|
|
1206
1200
|
/**
|
|
1207
1201
|
* Encrypt and update the vault with the given authentication data.
|
|
1208
1202
|
*
|
|
1209
1203
|
* @param params - The parameters for updating the vault.
|
|
1210
1204
|
* @param params.password - The password to encrypt the vault.
|
|
1211
|
-
* @param params.
|
|
1212
|
-
* @param params.
|
|
1205
|
+
* @param params.rawToprfEncryptionKey - The TOPRF encryption key.
|
|
1206
|
+
* @param params.rawToprfPwEncryptionKey - The TOPRF password encryption key.
|
|
1207
|
+
* @param params.rawToprfAuthKeyPair - The TOPRF authentication key pair.
|
|
1213
1208
|
* @returns A promise that resolves to the updated vault.
|
|
1214
1209
|
*/
|
|
1215
|
-
async function _SeedlessOnboardingController_updateVault({ password,
|
|
1210
|
+
async function _SeedlessOnboardingController_updateVault({ password, rawToprfEncryptionKey, rawToprfPwEncryptionKey, rawToprfAuthKeyPair, }) {
|
|
1216
1211
|
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withVaultLock).call(this, async () => {
|
|
1212
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
|
|
1217
1213
|
assertIsValidPassword(password);
|
|
1214
|
+
const accessToken = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_getAccessToken).call(this, password);
|
|
1215
|
+
const toprfEncryptionKey = bytesToBase64(rawToprfEncryptionKey);
|
|
1216
|
+
const toprfPwEncryptionKey = bytesToBase64(rawToprfPwEncryptionKey);
|
|
1217
|
+
const toprfAuthKeyPair = serializeAuthKeyPair(rawToprfAuthKeyPair);
|
|
1218
|
+
const serializedVaultData = JSON.stringify({
|
|
1219
|
+
toprfEncryptionKey,
|
|
1220
|
+
toprfPwEncryptionKey,
|
|
1221
|
+
toprfAuthKeyPair,
|
|
1222
|
+
revokeToken: this.state.revokeToken,
|
|
1223
|
+
accessToken,
|
|
1224
|
+
});
|
|
1218
1225
|
// Note that vault encryption using the password is a very costly operation as it involves deriving the encryption key
|
|
1219
1226
|
// from the password using an intentionally slow key derivation function.
|
|
1220
1227
|
// We should make sure that we only call it very intentionally.
|
|
1221
1228
|
const { vault, exportedKeyString } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_vaultEncryptor, "f").encryptWithDetail(password, serializedVaultData);
|
|
1222
1229
|
// Encrypt vault key.
|
|
1223
|
-
const aes = managedNonce(gcm)(
|
|
1230
|
+
const aes = managedNonce(gcm)(rawToprfPwEncryptionKey);
|
|
1224
1231
|
const encryptedKey = aes.encrypt(utf8ToBytes(exportedKeyString));
|
|
1232
|
+
// update the controller state after updating the vault
|
|
1225
1233
|
this.update((state) => {
|
|
1226
1234
|
state.vault = vault;
|
|
1227
1235
|
state.vaultEncryptionKey = exportedKeyString;
|
|
1228
|
-
state.vaultEncryptionSalt = JSON.parse(vault).salt;
|
|
1229
1236
|
state.encryptedSeedlessEncryptionKey = bytesToBase64(encryptedKey);
|
|
1237
|
+
state.toprfEncryptionKey = toprfEncryptionKey;
|
|
1238
|
+
state.toprfPwEncryptionKey = toprfPwEncryptionKey;
|
|
1239
|
+
state.toprfAuthKeyPair = toprfAuthKeyPair;
|
|
1240
|
+
});
|
|
1241
|
+
// update the authPubKey in the state
|
|
1242
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_persistAuthPubKey).call(this, {
|
|
1243
|
+
authPubKey: rawToprfAuthKeyPair.pk,
|
|
1230
1244
|
});
|
|
1245
|
+
// unlock the controller
|
|
1246
|
+
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_setUnlocked).call(this);
|
|
1231
1247
|
});
|
|
1232
1248
|
}, _SeedlessOnboardingController_withControllerLock =
|
|
1233
1249
|
/**
|
|
@@ -1258,18 +1274,6 @@ async function _SeedlessOnboardingController_withControllerLock(callback) {
|
|
|
1258
1274
|
*/
|
|
1259
1275
|
async function _SeedlessOnboardingController_withVaultLock(callback) {
|
|
1260
1276
|
return await withLock(__classPrivateFieldGet(this, _SeedlessOnboardingController_vaultOperationMutex, "f"), callback);
|
|
1261
|
-
}, _SeedlessOnboardingController_serializeKeyData = function _SeedlessOnboardingController_serializeKeyData(encKey, pwEncKey, authKeyPair) {
|
|
1262
|
-
const b64EncodedEncKey = bytesToBase64(encKey);
|
|
1263
|
-
const b64EncodedPwEncKey = bytesToBase64(pwEncKey);
|
|
1264
|
-
const b64EncodedAuthKeyPair = JSON.stringify({
|
|
1265
|
-
sk: bigIntToHex(authKeyPair.sk),
|
|
1266
|
-
pk: bytesToBase64(authKeyPair.pk),
|
|
1267
|
-
});
|
|
1268
|
-
return {
|
|
1269
|
-
toprfEncryptionKey: b64EncodedEncKey,
|
|
1270
|
-
toprfPwEncryptionKey: b64EncodedPwEncKey,
|
|
1271
|
-
toprfAuthKeyPair: b64EncodedAuthKeyPair,
|
|
1272
|
-
};
|
|
1273
1277
|
}, _SeedlessOnboardingController_parseVaultData = function _SeedlessOnboardingController_parseVaultData(data) {
|
|
1274
1278
|
if (typeof data !== 'string') {
|
|
1275
1279
|
throw new Error(SeedlessOnboardingControllerErrorMessage.InvalidVaultData);
|
|
@@ -1284,11 +1288,7 @@ async function _SeedlessOnboardingController_withVaultLock(callback) {
|
|
|
1284
1288
|
assertIsValidVaultData(parsedVaultData);
|
|
1285
1289
|
const rawToprfEncryptionKey = base64ToBytes(parsedVaultData.toprfEncryptionKey);
|
|
1286
1290
|
const rawToprfPwEncryptionKey = base64ToBytes(parsedVaultData.toprfPwEncryptionKey);
|
|
1287
|
-
const
|
|
1288
|
-
const rawToprfAuthKeyPair = {
|
|
1289
|
-
sk: BigInt(parsedToprfAuthKeyPair.sk),
|
|
1290
|
-
pk: base64ToBytes(parsedToprfAuthKeyPair.pk),
|
|
1291
|
-
};
|
|
1291
|
+
const rawToprfAuthKeyPair = deserializAuthKeyPair(parsedVaultData.toprfAuthKeyPair);
|
|
1292
1292
|
return {
|
|
1293
1293
|
toprfEncryptionKey: rawToprfEncryptionKey,
|
|
1294
1294
|
toprfPwEncryptionKey: rawToprfPwEncryptionKey,
|
|
@@ -1296,10 +1296,17 @@ async function _SeedlessOnboardingController_withVaultLock(callback) {
|
|
|
1296
1296
|
revokeToken: parsedVaultData.revokeToken,
|
|
1297
1297
|
accessToken: parsedVaultData.accessToken,
|
|
1298
1298
|
};
|
|
1299
|
-
}, _SeedlessOnboardingController_assertIsUnlocked = function _SeedlessOnboardingController_assertIsUnlocked() {
|
|
1299
|
+
}, _SeedlessOnboardingController_assertIsUnlocked = function _SeedlessOnboardingController_assertIsUnlocked(value) {
|
|
1300
1300
|
if (!__classPrivateFieldGet(this, _SeedlessOnboardingController_isUnlocked, "f")) {
|
|
1301
1301
|
throw new Error(SeedlessOnboardingControllerErrorMessage.ControllerLocked);
|
|
1302
1302
|
}
|
|
1303
|
+
if (!value ||
|
|
1304
|
+
typeof value !== 'object' ||
|
|
1305
|
+
!('toprfEncryptionKey' in value) ||
|
|
1306
|
+
!('toprfPwEncryptionKey' in value) ||
|
|
1307
|
+
!('toprfAuthKeyPair' in value)) {
|
|
1308
|
+
throw new Error(SeedlessOnboardingControllerErrorMessage.VaultLocked);
|
|
1309
|
+
}
|
|
1303
1310
|
}, _SeedlessOnboardingController_assertIsAuthenticatedUser = function _SeedlessOnboardingController_assertIsAuthenticatedUser(value) {
|
|
1304
1311
|
if (!value ||
|
|
1305
1312
|
typeof value !== 'object' ||
|