@metamask-previews/seedless-onboarding-controller 1.0.0-preview-08a4995 → 1.0.0-preview-4e3fd4c0
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 +103 -26
- package/dist/SeedlessOnboardingController.cjs.map +1 -1
- package/dist/SeedlessOnboardingController.d.cts +17 -5
- package/dist/SeedlessOnboardingController.d.cts.map +1 -1
- package/dist/SeedlessOnboardingController.d.mts +17 -5
- package/dist/SeedlessOnboardingController.d.mts.map +1 -1
- package/dist/SeedlessOnboardingController.mjs +103 -26
- package/dist/SeedlessOnboardingController.mjs.map +1 -1
- package/dist/constants.cjs +1 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +2 -1
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +2 -1
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +1 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +4 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +4 -0
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -10,13 +10,16 @@ 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 _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_isUnlocked,
|
|
13
|
+
var _SeedlessOnboardingController_instances, _SeedlessOnboardingController_vaultEncryptor, _SeedlessOnboardingController_controllerOperationMutex, _SeedlessOnboardingController_vaultOperationMutex, _SeedlessOnboardingController_refreshJWTToken, _SeedlessOnboardingController_revokeRefreshToken, _SeedlessOnboardingController_isUnlocked, _SeedlessOnboardingController_recoverKeyringEncryptionKey, _SeedlessOnboardingController_setUnlocked, _SeedlessOnboardingController_persistOprfKey, _SeedlessOnboardingController_persistAuthPubKey, _SeedlessOnboardingController_storeKeyringEncryptionKey, _SeedlessOnboardingController_loadKeyringEncryptionKey, _SeedlessOnboardingController_recoverAuthPubKey, _SeedlessOnboardingController_recoverEncKey, _SeedlessOnboardingController_changeEncryptionKey, _SeedlessOnboardingController_encryptAndStoreSecretData, _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey, _SeedlessOnboardingController_withPersistedSecretMetadataBackupsState, _SeedlessOnboardingController_filterDupesAndUpdateSocialBackupsMetadata, _SeedlessOnboardingController_createNewVaultWithAuthData, _SeedlessOnboardingController_updateVault, _SeedlessOnboardingController_withControllerLock, _SeedlessOnboardingController_withVaultLock, _SeedlessOnboardingController_serializeKeyData, _SeedlessOnboardingController_parseVaultData, _SeedlessOnboardingController_assertIsUnlocked, _SeedlessOnboardingController_assertIsAuthenticatedUser, _SeedlessOnboardingController_assertIsSRPBackedUpUser, _SeedlessOnboardingController_assertPasswordInSync, _SeedlessOnboardingController_resetPasswordOutdatedCache, _SeedlessOnboardingController_assertIsValidVaultData, _SeedlessOnboardingController_isTokenExpiredError, _SeedlessOnboardingController_executeWithTokenRefresh;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.SeedlessOnboardingController = exports.getDefaultSeedlessOnboardingControllerState = void 0;
|
|
16
16
|
const auth_network_utils_1 = require("@metamask/auth-network-utils");
|
|
17
17
|
const base_controller_1 = require("@metamask/base-controller");
|
|
18
18
|
const toprf_secure_backup_1 = require("@metamask/toprf-secure-backup");
|
|
19
19
|
const utils_1 = require("@metamask/utils");
|
|
20
|
+
const aes_1 = require("@noble/ciphers/aes");
|
|
21
|
+
const utils_2 = require("@noble/ciphers/utils");
|
|
22
|
+
const webcrypto_1 = require("@noble/ciphers/webcrypto");
|
|
20
23
|
const secp256k1_1 = require("@noble/curves/secp256k1");
|
|
21
24
|
const async_mutex_1 = require("async-mutex");
|
|
22
25
|
const constants_1 = require("./constants.cjs");
|
|
@@ -99,6 +102,10 @@ const seedlessOnboardingMetadata = {
|
|
|
99
102
|
persist: false,
|
|
100
103
|
anonymous: true,
|
|
101
104
|
},
|
|
105
|
+
encryptedKeyringEncryptionKey: {
|
|
106
|
+
persist: true,
|
|
107
|
+
anonymous: true,
|
|
108
|
+
},
|
|
102
109
|
};
|
|
103
110
|
class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
104
111
|
/**
|
|
@@ -363,8 +370,16 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
363
370
|
skipLock: true, // skip lock since we already have the lock
|
|
364
371
|
});
|
|
365
372
|
const attemptChangePassword = async () => {
|
|
373
|
+
// load keyring encryption key if it exists
|
|
374
|
+
let keyringEncryptionKey;
|
|
375
|
+
if (this.state.encryptedKeyringEncryptionKey) {
|
|
376
|
+
keyringEncryptionKey = await this.loadKeyringEncryptionKey();
|
|
377
|
+
}
|
|
366
378
|
// update the encryption key with new password and update the Metadata Store
|
|
367
|
-
const { encKey: newEncKey, authKeyPair: newAuthKeyPair } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_changeEncryptionKey).call(this,
|
|
379
|
+
const { encKey: newEncKey, authKeyPair: newAuthKeyPair } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_changeEncryptionKey).call(this, {
|
|
380
|
+
oldPassword,
|
|
381
|
+
newPassword,
|
|
382
|
+
});
|
|
368
383
|
// update and encrypt the vault with new password
|
|
369
384
|
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_createNewVaultWithAuthData).call(this, {
|
|
370
385
|
password: newPassword,
|
|
@@ -375,6 +390,10 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
375
390
|
authPubKey: newAuthKeyPair.pk,
|
|
376
391
|
});
|
|
377
392
|
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_resetPasswordOutdatedCache).call(this);
|
|
393
|
+
// store the keyring encryption key if it exists
|
|
394
|
+
if (keyringEncryptionKey) {
|
|
395
|
+
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_storeKeyringEncryptionKey).call(this, newEncKey, keyringEncryptionKey);
|
|
396
|
+
}
|
|
378
397
|
};
|
|
379
398
|
try {
|
|
380
399
|
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_executeWithTokenRefresh).call(this, attemptChangePassword, 'changePassword');
|
|
@@ -467,17 +486,12 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
467
486
|
* persist the latest global password authPubKey
|
|
468
487
|
*
|
|
469
488
|
* @param params - The parameters for syncing the latest global password.
|
|
470
|
-
* @param params.oldPassword - The old password to verify.
|
|
471
489
|
* @param params.globalPassword - The latest global password.
|
|
472
490
|
* @returns A promise that resolves to the success of the operation.
|
|
473
491
|
*/
|
|
474
|
-
async syncLatestGlobalPassword({
|
|
492
|
+
async syncLatestGlobalPassword({ globalPassword, }) {
|
|
475
493
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
|
|
476
494
|
const doSyncPassword = async () => {
|
|
477
|
-
// verify correct old password
|
|
478
|
-
await this.verifyVaultPassword(oldPassword, {
|
|
479
|
-
skipLock: true, // skip lock since we already have the lock
|
|
480
|
-
});
|
|
481
495
|
// update vault with latest globalPassword
|
|
482
496
|
const { encKey, authKeyPair } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, globalPassword);
|
|
483
497
|
// update and encrypt the vault with new password
|
|
@@ -503,18 +517,18 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
503
517
|
* @param params.globalPassword - The latest global password.
|
|
504
518
|
* @returns A promise that resolves to the password corresponding to the current authPubKey in state.
|
|
505
519
|
*/
|
|
506
|
-
async
|
|
520
|
+
async recoverKeyringEncryptionKey({ globalPassword, }) {
|
|
507
521
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_withControllerLock).call(this, async () => {
|
|
508
522
|
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_executeWithTokenRefresh).call(this, async () => {
|
|
509
523
|
const currentDeviceAuthPubKey = __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverAuthPubKey).call(this);
|
|
510
|
-
const {
|
|
511
|
-
|
|
524
|
+
const { keyringEncryptionKey } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverKeyringEncryptionKey).call(this, {
|
|
525
|
+
targetAuthPubKey: currentDeviceAuthPubKey,
|
|
512
526
|
globalPassword,
|
|
513
527
|
});
|
|
514
528
|
return {
|
|
515
|
-
|
|
529
|
+
keyringEncryptionKey,
|
|
516
530
|
};
|
|
517
|
-
}, '
|
|
531
|
+
}, 'recoverKeyringEncryptionKey');
|
|
518
532
|
});
|
|
519
533
|
}
|
|
520
534
|
/**
|
|
@@ -569,6 +583,26 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
569
583
|
return defaultState;
|
|
570
584
|
});
|
|
571
585
|
}
|
|
586
|
+
/**
|
|
587
|
+
* Store the keyring encryption key in state, encrypted under the current
|
|
588
|
+
* encryption key.
|
|
589
|
+
*
|
|
590
|
+
* @param keyringEncryptionKey - The keyring encryption key.
|
|
591
|
+
*/
|
|
592
|
+
async storeKeyringEncryptionKey(keyringEncryptionKey) {
|
|
593
|
+
const { toprfEncryptionKey: encKey } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey).call(this);
|
|
594
|
+
await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_storeKeyringEncryptionKey).call(this, encKey, keyringEncryptionKey);
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Load the keyring encryption key from state, decrypted under the current
|
|
598
|
+
* encryption key.
|
|
599
|
+
*
|
|
600
|
+
* @returns The keyring encryption key.
|
|
601
|
+
*/
|
|
602
|
+
async loadKeyringEncryptionKey() {
|
|
603
|
+
const { toprfEncryptionKey: encKey } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_unlockVaultAndGetBackupEncKey).call(this);
|
|
604
|
+
return await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_loadKeyringEncryptionKey).call(this, encKey);
|
|
605
|
+
}
|
|
572
606
|
/**
|
|
573
607
|
* Refresh expired nodeAuthTokens using the stored refresh token.
|
|
574
608
|
*
|
|
@@ -654,24 +688,27 @@ class SeedlessOnboardingController extends base_controller_1.BaseController {
|
|
|
654
688
|
}
|
|
655
689
|
}
|
|
656
690
|
exports.SeedlessOnboardingController = SeedlessOnboardingController;
|
|
657
|
-
_SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardingController_controllerOperationMutex = new WeakMap(), _SeedlessOnboardingController_vaultOperationMutex = new WeakMap(), _SeedlessOnboardingController_refreshJWTToken = new WeakMap(), _SeedlessOnboardingController_revokeRefreshToken = new WeakMap(), _SeedlessOnboardingController_isUnlocked = new WeakMap(), _SeedlessOnboardingController_instances = new WeakSet(),
|
|
691
|
+
_SeedlessOnboardingController_vaultEncryptor = new WeakMap(), _SeedlessOnboardingController_controllerOperationMutex = new WeakMap(), _SeedlessOnboardingController_vaultOperationMutex = new WeakMap(), _SeedlessOnboardingController_refreshJWTToken = new WeakMap(), _SeedlessOnboardingController_revokeRefreshToken = new WeakMap(), _SeedlessOnboardingController_isUnlocked = new WeakMap(), _SeedlessOnboardingController_instances = new WeakSet(), _SeedlessOnboardingController_recoverKeyringEncryptionKey =
|
|
658
692
|
/**
|
|
659
|
-
* @description Fetch the
|
|
693
|
+
* @description Fetch the keyring encryption key corresponding to the targetAuthPubKey.
|
|
660
694
|
*
|
|
661
|
-
* @param params - The parameters for fetching the
|
|
662
|
-
* @param params.
|
|
695
|
+
* @param params - The parameters for fetching the keyring encryption key.
|
|
696
|
+
* @param params.targetAuthPubKey - The target public key of the keyring encryption key to recover.
|
|
663
697
|
* @param params.globalPassword - The latest global password.
|
|
664
|
-
* @returns A promise that resolves to the
|
|
698
|
+
* @returns A promise that resolves to the keyring encryption key corresponding to the current authPubKey in state.
|
|
665
699
|
*/
|
|
666
|
-
async function
|
|
700
|
+
async function _SeedlessOnboardingController_recoverKeyringEncryptionKey({ targetAuthPubKey, globalPassword, }) {
|
|
667
701
|
const { encKey: latestPwEncKey, authKeyPair: latestPwAuthKeyPair } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, globalPassword);
|
|
668
702
|
try {
|
|
669
703
|
const res = await this.toprfClient.recoverPassword({
|
|
670
|
-
targetPwPubKey,
|
|
704
|
+
targetPwPubKey: targetAuthPubKey,
|
|
671
705
|
curEncKey: latestPwEncKey,
|
|
672
706
|
curAuthKeyPair: latestPwAuthKeyPair,
|
|
673
707
|
});
|
|
674
|
-
|
|
708
|
+
const { password: recoveredEncryptionKeyBase64 } = res;
|
|
709
|
+
const recoveredEncryptionKey = (0, utils_1.base64ToBytes)(recoveredEncryptionKeyBase64);
|
|
710
|
+
const keyringEncryptionKey = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_loadKeyringEncryptionKey).call(this, recoveredEncryptionKey);
|
|
711
|
+
return { keyringEncryptionKey };
|
|
675
712
|
}
|
|
676
713
|
catch (error) {
|
|
677
714
|
if (__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_isTokenExpiredError).call(this, error)) {
|
|
@@ -713,6 +750,33 @@ async function _SeedlessOnboardingController_persistOprfKey(oprfKey, authPubKey)
|
|
|
713
750
|
this.update((state) => {
|
|
714
751
|
state.authPubKey = (0, utils_1.bytesToBase64)(params.authPubKey);
|
|
715
752
|
});
|
|
753
|
+
}, _SeedlessOnboardingController_storeKeyringEncryptionKey =
|
|
754
|
+
/**
|
|
755
|
+
* Encrypt the keyring encryption key and store it in state.
|
|
756
|
+
*
|
|
757
|
+
* @param encKey - The encryption key.
|
|
758
|
+
* @param keyringEncryptionKey - The keyring encryption key.
|
|
759
|
+
*/
|
|
760
|
+
async function _SeedlessOnboardingController_storeKeyringEncryptionKey(encKey, keyringEncryptionKey) {
|
|
761
|
+
const aes = (0, webcrypto_1.managedNonce)(aes_1.gcm)(encKey);
|
|
762
|
+
const encryptedKeyringEncryptionKey = aes.encrypt((0, utils_2.utf8ToBytes)(keyringEncryptionKey));
|
|
763
|
+
this.update((state) => {
|
|
764
|
+
state.encryptedKeyringEncryptionKey = (0, utils_1.bytesToBase64)(encryptedKeyringEncryptionKey);
|
|
765
|
+
});
|
|
766
|
+
}, _SeedlessOnboardingController_loadKeyringEncryptionKey =
|
|
767
|
+
/**
|
|
768
|
+
* Decrypt the keyring encryption key from state.
|
|
769
|
+
*
|
|
770
|
+
* @param encKey - The encryption key.
|
|
771
|
+
* @returns The keyring encryption key.
|
|
772
|
+
*/
|
|
773
|
+
async function _SeedlessOnboardingController_loadKeyringEncryptionKey(encKey) {
|
|
774
|
+
const { encryptedKeyringEncryptionKey: encryptedKey } = this.state;
|
|
775
|
+
assertIsEncryptedKeyringEncryptionKeySet(encryptedKey);
|
|
776
|
+
const encryptedPasswordBytes = (0, utils_1.base64ToBytes)(encryptedKey);
|
|
777
|
+
const aes = (0, webcrypto_1.managedNonce)(aes_1.gcm)(encKey);
|
|
778
|
+
const password = aes.decrypt(encryptedPasswordBytes);
|
|
779
|
+
return (0, utils_2.bytesToUtf8)(password);
|
|
716
780
|
}, _SeedlessOnboardingController_recoverAuthPubKey = function _SeedlessOnboardingController_recoverAuthPubKey() {
|
|
717
781
|
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsSRPBackedUpUser).call(this, this.state);
|
|
718
782
|
const { authPubKey } = this.state;
|
|
@@ -751,15 +815,16 @@ async function _SeedlessOnboardingController_recoverEncKey(password) {
|
|
|
751
815
|
/**
|
|
752
816
|
* Update the encryption key with new password and update the Metadata Store with new encryption key.
|
|
753
817
|
*
|
|
754
|
-
* @param
|
|
755
|
-
* @param oldPassword - The old password to verify.
|
|
818
|
+
* @param params - The function parameters.
|
|
819
|
+
* @param params.oldPassword - The old password to verify.
|
|
820
|
+
* @param params.newPassword - The new password to update.
|
|
756
821
|
* @returns A promise that resolves to new encryption key and authentication key pair.
|
|
757
822
|
*/
|
|
758
|
-
async function _SeedlessOnboardingController_changeEncryptionKey(newPassword,
|
|
823
|
+
async function _SeedlessOnboardingController_changeEncryptionKey({ oldPassword, newPassword, }) {
|
|
759
824
|
__classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_assertIsAuthenticatedUser).call(this, this.state);
|
|
760
825
|
const { authConnectionId, groupedAuthConnectionId, userId } = this.state;
|
|
761
826
|
const { encKey, authKeyPair, keyShareIndex: newKeyShareIndex, } = await __classPrivateFieldGet(this, _SeedlessOnboardingController_instances, "m", _SeedlessOnboardingController_recoverEncKey).call(this, oldPassword);
|
|
762
|
-
|
|
827
|
+
const result = await this.toprfClient.changeEncKey({
|
|
763
828
|
nodeAuthTokens: this.state.nodeAuthTokens,
|
|
764
829
|
authConnectionId,
|
|
765
830
|
groupedAuthConnectionId,
|
|
@@ -767,9 +832,10 @@ async function _SeedlessOnboardingController_changeEncryptionKey(newPassword, ol
|
|
|
767
832
|
oldEncKey: encKey,
|
|
768
833
|
oldAuthKeyPair: authKeyPair,
|
|
769
834
|
newKeyShareIndex,
|
|
770
|
-
oldPassword,
|
|
835
|
+
oldPassword: (0, utils_1.bytesToBase64)(encKey),
|
|
771
836
|
newPassword,
|
|
772
837
|
});
|
|
838
|
+
return result;
|
|
773
839
|
}, _SeedlessOnboardingController_encryptAndStoreSecretData =
|
|
774
840
|
/**
|
|
775
841
|
* Encrypt and store the secret data backup in the metadata store.
|
|
@@ -1196,4 +1262,15 @@ async function withLock(mutex, callback) {
|
|
|
1196
1262
|
releaseLock();
|
|
1197
1263
|
}
|
|
1198
1264
|
}
|
|
1265
|
+
/**
|
|
1266
|
+
* Assert that the provided encrypted keyring encryption key is a valid non-empty string.
|
|
1267
|
+
*
|
|
1268
|
+
* @param encryptedKeyringEncryptionKey - The encrypted keyring encryption key to check.
|
|
1269
|
+
* @throws If the encrypted keyring encryption key is not a valid string.
|
|
1270
|
+
*/
|
|
1271
|
+
function assertIsEncryptedKeyringEncryptionKeySet(encryptedKeyringEncryptionKey) {
|
|
1272
|
+
if (!encryptedKeyringEncryptionKey) {
|
|
1273
|
+
throw new Error(constants_1.SeedlessOnboardingControllerErrorMessage.EncryptedKeyringEncryptionKeyNotSet);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1199
1276
|
//# sourceMappingURL=SeedlessOnboardingController.cjs.map
|