@metamask-previews/keyring-controller 24.0.0-preview-70abd50a → 24.0.0-preview-536ed51
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 -20
- package/dist/KeyringController.cjs +138 -119
- package/dist/KeyringController.cjs.map +1 -1
- package/dist/KeyringController.d.cts +34 -52
- package/dist/KeyringController.d.cts.map +1 -1
- package/dist/KeyringController.d.mts +34 -52
- package/dist/KeyringController.d.mts.map +1 -1
- package/dist/KeyringController.mjs +139 -120
- 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 +2 -2
|
@@ -9,7 +9,7 @@ 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 _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings,
|
|
12
|
+
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;
|
|
13
13
|
function $importDefault(module) {
|
|
14
14
|
if (module?.__esModule) {
|
|
15
15
|
return module.default;
|
|
@@ -18,6 +18,7 @@ function $importDefault(module) {
|
|
|
18
18
|
}
|
|
19
19
|
import { isValidPrivate, getBinarySize } from "@ethereumjs/util";
|
|
20
20
|
import { BaseController } from "@metamask/base-controller";
|
|
21
|
+
import * as encryptorUtils from "@metamask/browser-passworder";
|
|
21
22
|
import { HdKeyring } from "@metamask/eth-hd-keyring";
|
|
22
23
|
import { normalize as ethNormalize } from "@metamask/eth-sig-util";
|
|
23
24
|
import SimpleKeyring from "@metamask/eth-simple-keyring";
|
|
@@ -27,7 +28,7 @@ import $Wallet from "ethereumjs-wallet";
|
|
|
27
28
|
const { thirdparty: importers } = $Wallet;
|
|
28
29
|
const Wallet = $importDefault($Wallet);
|
|
29
30
|
import $lodash from "lodash";
|
|
30
|
-
const {
|
|
31
|
+
const { isEqual } = $lodash;
|
|
31
32
|
// When generating a ULID within the same millisecond, monotonicFactory provides some guarantees regarding sort order.
|
|
32
33
|
import { ulid } from "ulid";
|
|
33
34
|
import { KeyringControllerError } from "./constants.mjs";
|
|
@@ -112,6 +113,23 @@ function assertHasUint8ArrayMnemonic(keyring) {
|
|
|
112
113
|
throw new Error("Can't get mnemonic bytes from keyring");
|
|
113
114
|
}
|
|
114
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Assert that the provided encryptor supports
|
|
118
|
+
* encryption and encryption key export.
|
|
119
|
+
*
|
|
120
|
+
* @param encryptor - The encryptor to check.
|
|
121
|
+
* @throws If the encryptor does not support key encryption.
|
|
122
|
+
*/
|
|
123
|
+
function assertIsExportableKeyEncryptor(encryptor) {
|
|
124
|
+
if (!('importKey' in encryptor &&
|
|
125
|
+
typeof encryptor.importKey === 'function' &&
|
|
126
|
+
'decryptWithKey' in encryptor &&
|
|
127
|
+
typeof encryptor.decryptWithKey === 'function' &&
|
|
128
|
+
'encryptWithKey' in encryptor &&
|
|
129
|
+
typeof encryptor.encryptWithKey === 'function')) {
|
|
130
|
+
throw new Error(KeyringControllerError.UnsupportedEncryptionKeyExport);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
115
133
|
/**
|
|
116
134
|
* Assert that the provided password is a valid non-empty string.
|
|
117
135
|
*
|
|
@@ -213,11 +231,12 @@ export class KeyringController extends BaseController {
|
|
|
213
231
|
* @param options - Initial options used to configure this controller
|
|
214
232
|
* @param options.encryptor - An optional object for defining encryption schemes.
|
|
215
233
|
* @param options.keyringBuilders - Set a new name for account.
|
|
234
|
+
* @param options.cacheEncryptionKey - Whether to cache or not encryption key.
|
|
216
235
|
* @param options.messenger - A restricted messenger.
|
|
217
236
|
* @param options.state - Initial state to set on this controller.
|
|
218
237
|
*/
|
|
219
238
|
constructor(options) {
|
|
220
|
-
const { encryptor, keyringBuilders, messenger, state } = options;
|
|
239
|
+
const { encryptor = encryptorUtils, keyringBuilders, messenger, state, } = options;
|
|
221
240
|
super({
|
|
222
241
|
name,
|
|
223
242
|
metadata: {
|
|
@@ -263,15 +282,22 @@ export class KeyringController extends BaseController {
|
|
|
263
282
|
_KeyringController_vaultOperationMutex.set(this, new Mutex());
|
|
264
283
|
_KeyringController_keyringBuilders.set(this, void 0);
|
|
265
284
|
_KeyringController_encryptor.set(this, void 0);
|
|
285
|
+
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
266
286
|
_KeyringController_keyrings.set(this, void 0);
|
|
267
287
|
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
268
|
-
|
|
288
|
+
_KeyringController_password.set(this, void 0);
|
|
269
289
|
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
270
290
|
? keyringBuilders.concat(defaultKeyringBuilders)
|
|
271
291
|
: defaultKeyringBuilders, "f");
|
|
272
292
|
__classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
|
|
273
293
|
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
274
294
|
__classPrivateFieldSet(this, _KeyringController_unsupportedKeyrings, [], "f");
|
|
295
|
+
// This option allows the controller to cache an exported key
|
|
296
|
+
// for use in decrypting and encrypting data without password
|
|
297
|
+
__classPrivateFieldSet(this, _KeyringController_cacheEncryptionKey, Boolean(options.cacheEncryptionKey), "f");
|
|
298
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
299
|
+
assertIsExportableKeyEncryptor(encryptor);
|
|
300
|
+
}
|
|
275
301
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
|
|
276
302
|
}
|
|
277
303
|
/**
|
|
@@ -642,7 +668,7 @@ export class KeyringController extends BaseController {
|
|
|
642
668
|
async setLocked() {
|
|
643
669
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
644
670
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
645
|
-
__classPrivateFieldSet(this,
|
|
671
|
+
__classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
|
|
646
672
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
647
673
|
this.update((state) => {
|
|
648
674
|
state.isUnlocked = false;
|
|
@@ -824,11 +850,22 @@ export class KeyringController extends BaseController {
|
|
|
824
850
|
*/
|
|
825
851
|
changePassword(password) {
|
|
826
852
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
853
|
+
// If the password is the same, do nothing.
|
|
854
|
+
if (__classPrivateFieldGet(this, _KeyringController_password, "f") === password) {
|
|
855
|
+
return Promise.resolve();
|
|
856
|
+
}
|
|
827
857
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
828
858
|
assertIsValidPassword(password);
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
859
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
860
|
+
// We need to clear encryption key and salt from state
|
|
861
|
+
// to force the controller to re-encrypt the vault using
|
|
862
|
+
// the new password.
|
|
863
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
864
|
+
this.update((state) => {
|
|
865
|
+
delete state.encryptionKey;
|
|
866
|
+
delete state.encryptionSalt;
|
|
867
|
+
});
|
|
868
|
+
}
|
|
832
869
|
});
|
|
833
870
|
}
|
|
834
871
|
/**
|
|
@@ -837,15 +874,12 @@ export class KeyringController extends BaseController {
|
|
|
837
874
|
* consistency with the vault salt.
|
|
838
875
|
*
|
|
839
876
|
* @param encryptionKey - Key to unlock the keychain.
|
|
840
|
-
* @param
|
|
877
|
+
* @param encryptionSalt - Optional salt to unlock the keychain.
|
|
841
878
|
* @returns Promise resolving when the operation completes.
|
|
842
879
|
*/
|
|
843
|
-
async submitEncryptionKey(encryptionKey,
|
|
880
|
+
async submitEncryptionKey(encryptionKey, encryptionSalt) {
|
|
844
881
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
845
|
-
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this,
|
|
846
|
-
encryptionKey,
|
|
847
|
-
keyDerivationSalt,
|
|
848
|
-
});
|
|
882
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt);
|
|
849
883
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
850
884
|
return result;
|
|
851
885
|
});
|
|
@@ -872,8 +906,9 @@ export class KeyringController extends BaseController {
|
|
|
872
906
|
async exportEncryptionKey() {
|
|
873
907
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
874
908
|
return await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async () => {
|
|
875
|
-
|
|
876
|
-
|
|
909
|
+
const { encryptionKey } = this.state;
|
|
910
|
+
assertIsEncryptionKeySet(encryptionKey);
|
|
911
|
+
return encryptionKey;
|
|
877
912
|
});
|
|
878
913
|
}
|
|
879
914
|
/**
|
|
@@ -885,7 +920,7 @@ export class KeyringController extends BaseController {
|
|
|
885
920
|
*/
|
|
886
921
|
async submitPassword(password) {
|
|
887
922
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
888
|
-
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this,
|
|
923
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password);
|
|
889
924
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
890
925
|
return result;
|
|
891
926
|
});
|
|
@@ -895,12 +930,6 @@ export class KeyringController extends BaseController {
|
|
|
895
930
|
// can attempt to upgrade the vault.
|
|
896
931
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
897
932
|
if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
|
|
898
|
-
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
|
|
899
|
-
// If the vault is being upgraded, we want to ignore the metadata
|
|
900
|
-
// that is already in the vault, so we can effectively
|
|
901
|
-
// re-encrypt the vault with the new encryption config.
|
|
902
|
-
ignoreExistingVault: true,
|
|
903
|
-
});
|
|
904
933
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
|
|
905
934
|
}
|
|
906
935
|
});
|
|
@@ -962,7 +991,7 @@ export class KeyringController extends BaseController {
|
|
|
962
991
|
return keyring.type;
|
|
963
992
|
}
|
|
964
993
|
}
|
|
965
|
-
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(),
|
|
994
|
+
_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() {
|
|
966
995
|
this.messenger.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
967
996
|
this.messenger.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
|
|
968
997
|
this.messenger.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
@@ -1021,70 +1050,10 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
|
|
|
1021
1050
|
delete state.encryptionKey;
|
|
1022
1051
|
delete state.encryptionSalt;
|
|
1023
1052
|
});
|
|
1024
|
-
|
|
1025
|
-
ignoreExistingVault: true,
|
|
1026
|
-
});
|
|
1053
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1027
1054
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1028
1055
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
|
|
1029
1056
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
1030
|
-
}, _KeyringController_deriveEncryptionKey =
|
|
1031
|
-
/**
|
|
1032
|
-
* Derive the vault encryption key from the provided password, and
|
|
1033
|
-
* assign it to the instance variable for later use with cryptographic
|
|
1034
|
-
* functions.
|
|
1035
|
-
*
|
|
1036
|
-
* When the controller has a vault in its state, the key is derived
|
|
1037
|
-
* using the salt from the vault. If the vault is empty, a new salt
|
|
1038
|
-
* is generated and used to derive the key.
|
|
1039
|
-
*
|
|
1040
|
-
* If `options.ignoreExistingVault` is set to `false`, the existing
|
|
1041
|
-
* vault is completely ignored: the new key won't be able to decrypt
|
|
1042
|
-
* the existing vault, and should be used to re-encrypt it.
|
|
1043
|
-
*
|
|
1044
|
-
* @param password - The password to use for decryption or derivation.
|
|
1045
|
-
* @param options - Options for the key derivation.
|
|
1046
|
-
* @param options.ignoreExistingVault - Whether to use the existing vault salt and key metadata
|
|
1047
|
-
*/
|
|
1048
|
-
async function _KeyringController_deriveEncryptionKey(password, options = {
|
|
1049
|
-
ignoreExistingVault: false,
|
|
1050
|
-
}) {
|
|
1051
|
-
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1052
|
-
const { vault } = this.state;
|
|
1053
|
-
if (typeof password !== 'string') {
|
|
1054
|
-
throw new TypeError(KeyringControllerError.WrongPasswordType);
|
|
1055
|
-
}
|
|
1056
|
-
let serializedEncryptionKey, salt;
|
|
1057
|
-
if (vault && !options.ignoreExistingVault) {
|
|
1058
|
-
// The `decryptWithDetail` method is being used here instead of
|
|
1059
|
-
// `keyFromPassword` + `exportKey` to let the encryptor handle
|
|
1060
|
-
// any legacy encryption formats and metadata that might be
|
|
1061
|
-
// present (or absent) in the vault.
|
|
1062
|
-
const { exportedKeyString, salt: existingSalt } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, vault);
|
|
1063
|
-
serializedEncryptionKey = exportedKeyString;
|
|
1064
|
-
salt = existingSalt;
|
|
1065
|
-
}
|
|
1066
|
-
else {
|
|
1067
|
-
salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
|
|
1068
|
-
serializedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true));
|
|
1069
|
-
}
|
|
1070
|
-
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1071
|
-
salt,
|
|
1072
|
-
serialized: serializedEncryptionKey,
|
|
1073
|
-
}, "f");
|
|
1074
|
-
}, _KeyringController_setEncryptionKey = function _KeyringController_setEncryptionKey(encryptionKey, keyDerivationSalt) {
|
|
1075
|
-
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1076
|
-
if (typeof encryptionKey !== 'string' ||
|
|
1077
|
-
typeof keyDerivationSalt !== 'string') {
|
|
1078
|
-
throw new TypeError(KeyringControllerError.WrongEncryptionKeyType);
|
|
1079
|
-
}
|
|
1080
|
-
const { vault } = this.state;
|
|
1081
|
-
if (vault && JSON.parse(vault).salt !== keyDerivationSalt) {
|
|
1082
|
-
throw new Error(KeyringControllerError.ExpiredCredentials);
|
|
1083
|
-
}
|
|
1084
|
-
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1085
|
-
salt: keyDerivationSalt,
|
|
1086
|
-
serialized: encryptionKey,
|
|
1087
|
-
}, "f");
|
|
1088
1057
|
}, _KeyringController_verifySeedPhrase =
|
|
1089
1058
|
/**
|
|
1090
1059
|
* Internal non-exclusive method to verify the seed phrase.
|
|
@@ -1165,7 +1134,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1165
1134
|
return serializedKeyrings;
|
|
1166
1135
|
}, _KeyringController_getSessionState =
|
|
1167
1136
|
/**
|
|
1168
|
-
* Get a snapshot of session data held by
|
|
1137
|
+
* Get a snapshot of session data held by class variables.
|
|
1169
1138
|
*
|
|
1170
1139
|
* @returns An object with serialized keyrings, keyrings metadata,
|
|
1171
1140
|
* and the user password.
|
|
@@ -1173,7 +1142,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1173
1142
|
async function _KeyringController_getSessionState() {
|
|
1174
1143
|
return {
|
|
1175
1144
|
keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
|
|
1176
|
-
|
|
1145
|
+
password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
|
|
1177
1146
|
};
|
|
1178
1147
|
}, _KeyringController_restoreSerializedKeyrings =
|
|
1179
1148
|
/**
|
|
@@ -1202,27 +1171,54 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
|
|
|
1202
1171
|
* Unlock Keyrings, decrypting the vault and deserializing all
|
|
1203
1172
|
* keyrings contained in it, using a password or an encryption key with salt.
|
|
1204
1173
|
*
|
|
1205
|
-
* @param
|
|
1174
|
+
* @param password - The keyring controller password.
|
|
1175
|
+
* @param encryptionKey - An exported key string to unlock keyrings with.
|
|
1176
|
+
* @param encryptionSalt - The salt used to encrypt the vault.
|
|
1206
1177
|
* @returns A promise resolving to the deserialized keyrings array.
|
|
1207
1178
|
*/
|
|
1208
|
-
async function _KeyringController_unlockKeyrings(
|
|
1179
|
+
async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
|
|
1209
1180
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1210
|
-
|
|
1181
|
+
const encryptedVault = this.state.vault;
|
|
1182
|
+
if (!encryptedVault) {
|
|
1211
1183
|
throw new Error(KeyringControllerError.VaultError);
|
|
1212
1184
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1185
|
+
let vault;
|
|
1186
|
+
const updatedState = {};
|
|
1187
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
1188
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
1189
|
+
if (password) {
|
|
1190
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
|
|
1191
|
+
vault = result.vault;
|
|
1192
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1193
|
+
updatedState.encryptionKey = result.exportedKeyString;
|
|
1194
|
+
updatedState.encryptionSalt = result.salt;
|
|
1195
|
+
}
|
|
1196
|
+
else {
|
|
1197
|
+
const parsedEncryptedVault = JSON.parse(encryptedVault);
|
|
1198
|
+
if (encryptionSalt && encryptionSalt !== parsedEncryptedVault.salt) {
|
|
1199
|
+
throw new Error(KeyringControllerError.ExpiredCredentials);
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
encryptionSalt = parsedEncryptedVault.salt;
|
|
1203
|
+
}
|
|
1204
|
+
if (typeof encryptionKey !== 'string') {
|
|
1205
|
+
throw new TypeError(KeyringControllerError.WrongPasswordType);
|
|
1206
|
+
}
|
|
1207
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1208
|
+
vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1209
|
+
// This call is required on the first call because encryptionKey
|
|
1210
|
+
// is not yet inside the memStore
|
|
1211
|
+
updatedState.encryptionKey = encryptionKey;
|
|
1212
|
+
updatedState.encryptionSalt = encryptionSalt;
|
|
1213
|
+
}
|
|
1216
1214
|
}
|
|
1217
1215
|
else {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1216
|
+
if (typeof password !== 'string') {
|
|
1217
|
+
throw new TypeError(KeyringControllerError.WrongPasswordType);
|
|
1218
|
+
}
|
|
1219
|
+
vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedVault);
|
|
1220
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1223
1221
|
}
|
|
1224
|
-
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1225
|
-
const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1226
1222
|
if (!isSerializedKeyringsArray(vault)) {
|
|
1227
1223
|
throw new Error(KeyringControllerError.VaultDataError);
|
|
1228
1224
|
}
|
|
@@ -1230,8 +1226,10 @@ async function _KeyringController_unlockKeyrings(credentials) {
|
|
|
1230
1226
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1231
1227
|
this.update((state) => {
|
|
1232
1228
|
state.keyrings = updatedKeyrings;
|
|
1233
|
-
|
|
1234
|
-
|
|
1229
|
+
if (updatedState.encryptionKey || updatedState.encryptionSalt) {
|
|
1230
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1231
|
+
state.encryptionSalt = updatedState.encryptionSalt;
|
|
1232
|
+
}
|
|
1235
1233
|
});
|
|
1236
1234
|
return { keyrings, newMetadata };
|
|
1237
1235
|
});
|
|
@@ -1239,36 +1237,57 @@ async function _KeyringController_unlockKeyrings(credentials) {
|
|
|
1239
1237
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1240
1238
|
// Ensure no duplicate accounts are persisted.
|
|
1241
1239
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this);
|
|
1242
|
-
|
|
1240
|
+
const { encryptionKey, encryptionSalt, vault } = this.state;
|
|
1241
|
+
// READ THIS CAREFULLY:
|
|
1242
|
+
// We do check if the vault is still considered up-to-date, if not, we would not re-use the
|
|
1243
|
+
// cached key and we will re-generate a new one (based on the password).
|
|
1244
|
+
//
|
|
1245
|
+
// This helps doing seamless updates of the vault. Useful in case we change some cryptographic
|
|
1246
|
+
// parameters to the KDF.
|
|
1247
|
+
const useCachedKey = encryptionKey && vault && __classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated?.(vault);
|
|
1248
|
+
if (!__classPrivateFieldGet(this, _KeyringController_password, "f") && !encryptionKey) {
|
|
1243
1249
|
throw new Error(KeyringControllerError.MissingCredentials);
|
|
1244
1250
|
}
|
|
1245
1251
|
const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1246
1252
|
if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
|
|
1247
1253
|
throw new Error(KeyringControllerError.NoHdKeyring);
|
|
1248
1254
|
}
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1255
|
+
const updatedState = {};
|
|
1256
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
1257
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
1258
|
+
if (useCachedKey) {
|
|
1259
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1260
|
+
const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
|
|
1261
|
+
vaultJSON.salt = encryptionSalt;
|
|
1262
|
+
updatedState.vault = JSON.stringify(vaultJSON);
|
|
1263
|
+
}
|
|
1264
|
+
else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
|
|
1265
|
+
const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
1266
|
+
updatedState.vault = newVault;
|
|
1267
|
+
updatedState.encryptionKey = exportedKeyString;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
else {
|
|
1271
|
+
assertIsValidPassword(__classPrivateFieldGet(this, _KeyringController_password, "f"));
|
|
1272
|
+
updatedState.vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
1273
|
+
}
|
|
1274
|
+
if (!updatedState.vault) {
|
|
1275
|
+
throw new Error(KeyringControllerError.MissingVaultData);
|
|
1276
|
+
}
|
|
1260
1277
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1261
1278
|
this.update((state) => {
|
|
1262
1279
|
state.vault = updatedState.vault;
|
|
1263
1280
|
state.keyrings = updatedKeyrings;
|
|
1264
|
-
|
|
1265
|
-
|
|
1281
|
+
if (updatedState.encryptionKey) {
|
|
1282
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1283
|
+
state.encryptionSalt = JSON.parse(updatedState.vault).salt;
|
|
1284
|
+
}
|
|
1266
1285
|
});
|
|
1267
1286
|
return true;
|
|
1268
1287
|
});
|
|
1269
1288
|
}, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
|
|
1270
1289
|
const { vault } = this.state;
|
|
1271
|
-
if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1290
|
+
if (!vault || !__classPrivateFieldGet(this, _KeyringController_password, "f") || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1272
1291
|
return false;
|
|
1273
1292
|
}
|
|
1274
1293
|
return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
|
|
@@ -1502,13 +1521,13 @@ async function _KeyringController_persistOrRollback(callback) {
|
|
|
1502
1521
|
async function _KeyringController_withRollback(callback) {
|
|
1503
1522
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
|
|
1504
1523
|
const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1505
|
-
const
|
|
1524
|
+
const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
|
|
1506
1525
|
try {
|
|
1507
1526
|
return await callback({ releaseLock });
|
|
1508
1527
|
}
|
|
1509
1528
|
catch (e) {
|
|
1510
|
-
// Keyrings and
|
|
1511
|
-
__classPrivateFieldSet(this,
|
|
1529
|
+
// Keyrings and password are restored to their previous state
|
|
1530
|
+
__classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
|
|
1512
1531
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
|
|
1513
1532
|
throw e;
|
|
1514
1533
|
}
|