@metamask-previews/keyring-controller 24.0.0-preview-898a4135 → 24.0.0-preview-e8e08ff
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 -14
- package/dist/KeyringController.cjs +119 -107
- package/dist/KeyringController.cjs.map +1 -1
- package/dist/KeyringController.d.cts +18 -32
- package/dist/KeyringController.d.cts.map +1 -1
- package/dist/KeyringController.d.mts +18 -32
- package/dist/KeyringController.d.mts.map +1 -1
- package/dist/KeyringController.mjs +120 -108
- package/dist/KeyringController.mjs.map +1 -1
- package/dist/constants.cjs +0 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +0 -1
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +0 -1
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +0 -1
- package/dist/constants.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,20 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
### Added
|
|
11
|
-
|
|
12
|
-
- Added optional `SupportedKeyDerivationOptions` type parameter to the `ExportableKeyEncryptor` type ([#5963](https://github.com/MetaMask/core/pull/5963))
|
|
13
|
-
- This type parameter allows specifying the key derivation options supported by the injected encryptor.
|
|
14
|
-
|
|
15
|
-
### Changed
|
|
16
|
-
|
|
17
|
-
- **BREAKING:** The `KeyringController` constructor now requires an encryptor supporting the `keyFromPassword`, `exportKey` and `generateSalt` methods ([#5963](https://github.com/MetaMask/core/pull/5963))
|
|
18
|
-
|
|
19
|
-
### Removed
|
|
20
|
-
|
|
21
|
-
- **BREAKING:** The `cacheEncryptionKey` parameter has been removed from the `KeyringController` constructor options ([#5963](https://github.com/MetaMask/core/pull/5963))
|
|
22
|
-
- This parameter was previously used to enable encryption key in-memory caching, but it is no longer needed as the controller now always uses the latest encryption key.
|
|
23
|
-
|
|
24
10
|
## [24.0.0]
|
|
25
11
|
|
|
26
12
|
### Changed
|
|
@@ -36,7 +36,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
36
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
|
-
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings,
|
|
39
|
+
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_password, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_createNewVaultWithKeyring, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_getSessionState, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_isNewEncryptionAvailable, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_createKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_removeEmptyKeyrings, _KeyringController_assertNoDuplicateAccounts, _KeyringController_setUnlocked, _KeyringController_assertIsUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
41
|
exports.KeyringController = exports.getDefaultKeyringState = exports.keyringBuilderFactory = exports.SignTypedDataVersion = exports.AccountImportStrategy = exports.isCustodyKeyring = exports.KeyringTypes = void 0;
|
|
42
42
|
const util_1 = require("@ethereumjs/util");
|
|
@@ -254,6 +254,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
254
254
|
* @param options - Initial options used to configure this controller
|
|
255
255
|
* @param options.encryptor - An optional object for defining encryption schemes.
|
|
256
256
|
* @param options.keyringBuilders - Set a new name for account.
|
|
257
|
+
* @param options.cacheEncryptionKey - Whether to cache or not encryption key.
|
|
257
258
|
* @param options.messenger - A restricted messenger.
|
|
258
259
|
* @param options.state - Initial state to set on this controller.
|
|
259
260
|
*/
|
|
@@ -304,16 +305,22 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
304
305
|
_KeyringController_vaultOperationMutex.set(this, new async_mutex_1.Mutex());
|
|
305
306
|
_KeyringController_keyringBuilders.set(this, void 0);
|
|
306
307
|
_KeyringController_encryptor.set(this, void 0);
|
|
308
|
+
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
307
309
|
_KeyringController_keyrings.set(this, void 0);
|
|
308
310
|
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
309
|
-
|
|
311
|
+
_KeyringController_password.set(this, void 0);
|
|
310
312
|
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
311
313
|
? keyringBuilders.concat(defaultKeyringBuilders)
|
|
312
314
|
: defaultKeyringBuilders, "f");
|
|
313
|
-
assertIsExportableKeyEncryptor(encryptor);
|
|
314
315
|
__classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
|
|
315
316
|
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
316
317
|
__classPrivateFieldSet(this, _KeyringController_unsupportedKeyrings, [], "f");
|
|
318
|
+
// This option allows the controller to cache an exported key
|
|
319
|
+
// for use in decrypting and encrypting data without password
|
|
320
|
+
__classPrivateFieldSet(this, _KeyringController_cacheEncryptionKey, Boolean(options.cacheEncryptionKey), "f");
|
|
321
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
322
|
+
assertIsExportableKeyEncryptor(encryptor);
|
|
323
|
+
}
|
|
317
324
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
|
|
318
325
|
}
|
|
319
326
|
/**
|
|
@@ -684,7 +691,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
684
691
|
async setLocked() {
|
|
685
692
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
686
693
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
687
|
-
__classPrivateFieldSet(this,
|
|
694
|
+
__classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
|
|
688
695
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
689
696
|
this.update((state) => {
|
|
690
697
|
state.isUnlocked = false;
|
|
@@ -866,9 +873,22 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
866
873
|
*/
|
|
867
874
|
changePassword(password) {
|
|
868
875
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
876
|
+
// If the password is the same, do nothing.
|
|
877
|
+
if (__classPrivateFieldGet(this, _KeyringController_password, "f") === password) {
|
|
878
|
+
return Promise.resolve();
|
|
879
|
+
}
|
|
869
880
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
870
881
|
assertIsValidPassword(password);
|
|
871
|
-
|
|
882
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
883
|
+
// We need to clear encryption key and salt from state
|
|
884
|
+
// to force the controller to re-encrypt the vault using
|
|
885
|
+
// the new password.
|
|
886
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
887
|
+
this.update((state) => {
|
|
888
|
+
delete state.encryptionKey;
|
|
889
|
+
delete state.encryptionSalt;
|
|
890
|
+
});
|
|
891
|
+
}
|
|
872
892
|
});
|
|
873
893
|
}
|
|
874
894
|
/**
|
|
@@ -877,15 +897,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
877
897
|
* consistency with the vault salt.
|
|
878
898
|
*
|
|
879
899
|
* @param encryptionKey - Key to unlock the keychain.
|
|
880
|
-
* @param
|
|
900
|
+
* @param encryptionSalt - Optional salt to unlock the keychain.
|
|
881
901
|
* @returns Promise resolving when the operation completes.
|
|
882
902
|
*/
|
|
883
|
-
async submitEncryptionKey(encryptionKey,
|
|
903
|
+
async submitEncryptionKey(encryptionKey, encryptionSalt) {
|
|
884
904
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
885
|
-
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this,
|
|
886
|
-
encryptionKey,
|
|
887
|
-
keyDerivationSalt,
|
|
888
|
-
});
|
|
905
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt);
|
|
889
906
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
890
907
|
return result;
|
|
891
908
|
});
|
|
@@ -912,8 +929,9 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
912
929
|
async exportEncryptionKey() {
|
|
913
930
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
914
931
|
return await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async () => {
|
|
915
|
-
|
|
916
|
-
|
|
932
|
+
const { encryptionKey } = this.state;
|
|
933
|
+
assertIsEncryptionKeySet(encryptionKey);
|
|
934
|
+
return encryptionKey;
|
|
917
935
|
});
|
|
918
936
|
}
|
|
919
937
|
/**
|
|
@@ -925,7 +943,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
925
943
|
*/
|
|
926
944
|
async submitPassword(password) {
|
|
927
945
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
928
|
-
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this,
|
|
946
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password);
|
|
929
947
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
930
948
|
return result;
|
|
931
949
|
});
|
|
@@ -935,12 +953,6 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
935
953
|
// can attempt to upgrade the vault.
|
|
936
954
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
937
955
|
if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
|
|
938
|
-
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
|
|
939
|
-
// If the vault is being upgraded, we want to ignore the metadata
|
|
940
|
-
// that is already in the vault, so we can effectively
|
|
941
|
-
// re-encrypt the vault with the new encryption config.
|
|
942
|
-
useVaultKeyMetadata: false,
|
|
943
|
-
});
|
|
944
956
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
|
|
945
957
|
}
|
|
946
958
|
});
|
|
@@ -1003,7 +1015,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
1003
1015
|
}
|
|
1004
1016
|
}
|
|
1005
1017
|
exports.KeyringController = KeyringController;
|
|
1006
|
-
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(),
|
|
1018
|
+
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_cacheEncryptionKey = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(), _KeyringController_password = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
|
|
1007
1019
|
this.messenger.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
1008
1020
|
this.messenger.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
|
|
1009
1021
|
this.messenger.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
@@ -1062,60 +1074,10 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
|
|
|
1062
1074
|
delete state.encryptionKey;
|
|
1063
1075
|
delete state.encryptionSalt;
|
|
1064
1076
|
});
|
|
1065
|
-
|
|
1077
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1066
1078
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1067
1079
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
|
|
1068
1080
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
1069
|
-
}, _KeyringController_deriveEncryptionKey =
|
|
1070
|
-
/**
|
|
1071
|
-
* Derive the vault encryption key from the provided password, and
|
|
1072
|
-
* assign it to the instance variable for later use with cryptographic
|
|
1073
|
-
* functions.
|
|
1074
|
-
*
|
|
1075
|
-
* When the controller has a vault in its state, the key is derived
|
|
1076
|
-
* using the salt from the vault. If the vault is empty, a new salt
|
|
1077
|
-
* is generated and used to derive the key.
|
|
1078
|
-
*
|
|
1079
|
-
* @param password - The password to use for decryption or derivation.
|
|
1080
|
-
* @param options - Options for the key derivation.
|
|
1081
|
-
* @param options.useVaultKeyMetadata - Whether to use the vault key metadata
|
|
1082
|
-
*/
|
|
1083
|
-
async function _KeyringController_deriveEncryptionKey(password, options = {
|
|
1084
|
-
useVaultKeyMetadata: true,
|
|
1085
|
-
}) {
|
|
1086
|
-
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1087
|
-
const { vault } = this.state;
|
|
1088
|
-
if (typeof password !== 'string') {
|
|
1089
|
-
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1090
|
-
}
|
|
1091
|
-
let salt, keyMetadata;
|
|
1092
|
-
if (vault && options.useVaultKeyMetadata) {
|
|
1093
|
-
const parsedVault = JSON.parse(vault);
|
|
1094
|
-
salt = parsedVault.salt;
|
|
1095
|
-
keyMetadata = parsedVault.keyMetadata;
|
|
1096
|
-
}
|
|
1097
|
-
else {
|
|
1098
|
-
salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
|
|
1099
|
-
}
|
|
1100
|
-
const serializedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true, keyMetadata));
|
|
1101
|
-
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1102
|
-
salt,
|
|
1103
|
-
serialized: serializedEncryptionKey,
|
|
1104
|
-
}, "f");
|
|
1105
|
-
}, _KeyringController_setEncryptionKey = function _KeyringController_setEncryptionKey(encryptionKey, keyDerivationSalt) {
|
|
1106
|
-
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1107
|
-
if (typeof encryptionKey !== 'string' ||
|
|
1108
|
-
typeof keyDerivationSalt !== 'string') {
|
|
1109
|
-
throw new TypeError(constants_1.KeyringControllerError.WrongEncryptionKeyType);
|
|
1110
|
-
}
|
|
1111
|
-
const { vault } = this.state;
|
|
1112
|
-
if (vault && JSON.parse(vault).salt !== keyDerivationSalt) {
|
|
1113
|
-
throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
|
|
1114
|
-
}
|
|
1115
|
-
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1116
|
-
salt: keyDerivationSalt,
|
|
1117
|
-
serialized: encryptionKey,
|
|
1118
|
-
}, "f");
|
|
1119
1081
|
}, _KeyringController_verifySeedPhrase =
|
|
1120
1082
|
/**
|
|
1121
1083
|
* Internal non-exclusive method to verify the seed phrase.
|
|
@@ -1196,7 +1158,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1196
1158
|
return serializedKeyrings;
|
|
1197
1159
|
}, _KeyringController_getSessionState =
|
|
1198
1160
|
/**
|
|
1199
|
-
* Get a snapshot of session data held by
|
|
1161
|
+
* Get a snapshot of session data held by class variables.
|
|
1200
1162
|
*
|
|
1201
1163
|
* @returns An object with serialized keyrings, keyrings metadata,
|
|
1202
1164
|
* and the user password.
|
|
@@ -1204,7 +1166,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1204
1166
|
async function _KeyringController_getSessionState() {
|
|
1205
1167
|
return {
|
|
1206
1168
|
keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
|
|
1207
|
-
|
|
1169
|
+
password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
|
|
1208
1170
|
};
|
|
1209
1171
|
}, _KeyringController_restoreSerializedKeyrings =
|
|
1210
1172
|
/**
|
|
@@ -1233,27 +1195,54 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
|
|
|
1233
1195
|
* Unlock Keyrings, decrypting the vault and deserializing all
|
|
1234
1196
|
* keyrings contained in it, using a password or an encryption key with salt.
|
|
1235
1197
|
*
|
|
1236
|
-
* @param
|
|
1198
|
+
* @param password - The keyring controller password.
|
|
1199
|
+
* @param encryptionKey - An exported key string to unlock keyrings with.
|
|
1200
|
+
* @param encryptionSalt - The salt used to encrypt the vault.
|
|
1237
1201
|
* @returns A promise resolving to the deserialized keyrings array.
|
|
1238
1202
|
*/
|
|
1239
|
-
async function _KeyringController_unlockKeyrings(
|
|
1203
|
+
async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
|
|
1240
1204
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1241
|
-
|
|
1205
|
+
const encryptedVault = this.state.vault;
|
|
1206
|
+
if (!encryptedVault) {
|
|
1242
1207
|
throw new Error(constants_1.KeyringControllerError.VaultError);
|
|
1243
1208
|
}
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1209
|
+
let vault;
|
|
1210
|
+
const updatedState = {};
|
|
1211
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
1212
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
1213
|
+
if (password) {
|
|
1214
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
|
|
1215
|
+
vault = result.vault;
|
|
1216
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1217
|
+
updatedState.encryptionKey = result.exportedKeyString;
|
|
1218
|
+
updatedState.encryptionSalt = result.salt;
|
|
1219
|
+
}
|
|
1220
|
+
else {
|
|
1221
|
+
const parsedEncryptedVault = JSON.parse(encryptedVault);
|
|
1222
|
+
if (encryptionSalt && encryptionSalt !== parsedEncryptedVault.salt) {
|
|
1223
|
+
throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
|
|
1224
|
+
}
|
|
1225
|
+
else {
|
|
1226
|
+
encryptionSalt = parsedEncryptedVault.salt;
|
|
1227
|
+
}
|
|
1228
|
+
if (typeof encryptionKey !== 'string') {
|
|
1229
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1230
|
+
}
|
|
1231
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1232
|
+
vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1233
|
+
// This call is required on the first call because encryptionKey
|
|
1234
|
+
// is not yet inside the memStore
|
|
1235
|
+
updatedState.encryptionKey = encryptionKey;
|
|
1236
|
+
updatedState.encryptionSalt = encryptionSalt;
|
|
1237
|
+
}
|
|
1247
1238
|
}
|
|
1248
1239
|
else {
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1240
|
+
if (typeof password !== 'string') {
|
|
1241
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1242
|
+
}
|
|
1243
|
+
vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedVault);
|
|
1244
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1254
1245
|
}
|
|
1255
|
-
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1256
|
-
const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1257
1246
|
if (!isSerializedKeyringsArray(vault)) {
|
|
1258
1247
|
throw new Error(constants_1.KeyringControllerError.VaultDataError);
|
|
1259
1248
|
}
|
|
@@ -1261,8 +1250,10 @@ async function _KeyringController_unlockKeyrings(credentials) {
|
|
|
1261
1250
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1262
1251
|
this.update((state) => {
|
|
1263
1252
|
state.keyrings = updatedKeyrings;
|
|
1264
|
-
|
|
1265
|
-
|
|
1253
|
+
if (updatedState.encryptionKey || updatedState.encryptionSalt) {
|
|
1254
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1255
|
+
state.encryptionSalt = updatedState.encryptionSalt;
|
|
1256
|
+
}
|
|
1266
1257
|
});
|
|
1267
1258
|
return { keyrings, newMetadata };
|
|
1268
1259
|
});
|
|
@@ -1270,36 +1261,57 @@ async function _KeyringController_unlockKeyrings(credentials) {
|
|
|
1270
1261
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1271
1262
|
// Ensure no duplicate accounts are persisted.
|
|
1272
1263
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this);
|
|
1273
|
-
|
|
1264
|
+
const { encryptionKey, encryptionSalt, vault } = this.state;
|
|
1265
|
+
// READ THIS CAREFULLY:
|
|
1266
|
+
// We do check if the vault is still considered up-to-date, if not, we would not re-use the
|
|
1267
|
+
// cached key and we will re-generate a new one (based on the password).
|
|
1268
|
+
//
|
|
1269
|
+
// This helps doing seamless updates of the vault. Useful in case we change some cryptographic
|
|
1270
|
+
// parameters to the KDF.
|
|
1271
|
+
const useCachedKey = encryptionKey && vault && __classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated?.(vault);
|
|
1272
|
+
if (!__classPrivateFieldGet(this, _KeyringController_password, "f") && !encryptionKey) {
|
|
1274
1273
|
throw new Error(constants_1.KeyringControllerError.MissingCredentials);
|
|
1275
1274
|
}
|
|
1276
1275
|
const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1277
1276
|
if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
|
|
1278
1277
|
throw new Error(constants_1.KeyringControllerError.NoHdKeyring);
|
|
1279
1278
|
}
|
|
1280
|
-
const
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1279
|
+
const updatedState = {};
|
|
1280
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
1281
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
1282
|
+
if (useCachedKey) {
|
|
1283
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1284
|
+
const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
|
|
1285
|
+
vaultJSON.salt = encryptionSalt;
|
|
1286
|
+
updatedState.vault = JSON.stringify(vaultJSON);
|
|
1287
|
+
}
|
|
1288
|
+
else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
|
|
1289
|
+
const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
1290
|
+
updatedState.vault = newVault;
|
|
1291
|
+
updatedState.encryptionKey = exportedKeyString;
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
else {
|
|
1295
|
+
assertIsValidPassword(__classPrivateFieldGet(this, _KeyringController_password, "f"));
|
|
1296
|
+
updatedState.vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
1297
|
+
}
|
|
1298
|
+
if (!updatedState.vault) {
|
|
1299
|
+
throw new Error(constants_1.KeyringControllerError.MissingVaultData);
|
|
1300
|
+
}
|
|
1291
1301
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1292
1302
|
this.update((state) => {
|
|
1293
1303
|
state.vault = updatedState.vault;
|
|
1294
1304
|
state.keyrings = updatedKeyrings;
|
|
1295
|
-
|
|
1296
|
-
|
|
1305
|
+
if (updatedState.encryptionKey) {
|
|
1306
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1307
|
+
state.encryptionSalt = JSON.parse(updatedState.vault).salt;
|
|
1308
|
+
}
|
|
1297
1309
|
});
|
|
1298
1310
|
return true;
|
|
1299
1311
|
});
|
|
1300
1312
|
}, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
|
|
1301
1313
|
const { vault } = this.state;
|
|
1302
|
-
if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1314
|
+
if (!vault || !__classPrivateFieldGet(this, _KeyringController_password, "f") || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1303
1315
|
return false;
|
|
1304
1316
|
}
|
|
1305
1317
|
return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
|
|
@@ -1533,13 +1545,13 @@ async function _KeyringController_persistOrRollback(callback) {
|
|
|
1533
1545
|
async function _KeyringController_withRollback(callback) {
|
|
1534
1546
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
|
|
1535
1547
|
const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1536
|
-
const
|
|
1548
|
+
const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
|
|
1537
1549
|
try {
|
|
1538
1550
|
return await callback({ releaseLock });
|
|
1539
1551
|
}
|
|
1540
1552
|
catch (e) {
|
|
1541
|
-
// Keyrings and
|
|
1542
|
-
__classPrivateFieldSet(this,
|
|
1553
|
+
// Keyrings and password are restored to their previous state
|
|
1554
|
+
__classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
|
|
1543
1555
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
|
|
1544
1556
|
throw e;
|
|
1545
1557
|
}
|