@metamask-previews/keyring-controller 24.0.0-preview-c0feb25 → 24.0.0-preview-607c80f8
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 +20 -0
- package/dist/KeyringController.cjs +107 -138
- package/dist/KeyringController.cjs.map +1 -1
- package/dist/KeyringController.d.cts +41 -33
- package/dist/KeyringController.d.cts.map +1 -1
- package/dist/KeyringController.d.mts +41 -33
- package/dist/KeyringController.d.mts.map +1 -1
- package/dist/KeyringController.mjs +108 -139
- package/dist/KeyringController.mjs.map +1 -1
- package/dist/constants.cjs +1 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +1 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +1 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +1 -0
- package/dist/constants.mjs.map +1 -1
- package/package.json +2 -4
|
@@ -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,
|
|
12
|
+
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_encryptionKey, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_createNewVaultWithKeyring, _KeyringController_deriveEncryptionKey, _KeyringController_setEncryptionKey, _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,7 +18,6 @@ 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";
|
|
22
21
|
import { HdKeyring } from "@metamask/eth-hd-keyring";
|
|
23
22
|
import { normalize as ethNormalize } from "@metamask/eth-sig-util";
|
|
24
23
|
import SimpleKeyring from "@metamask/eth-simple-keyring";
|
|
@@ -28,7 +27,7 @@ import $Wallet from "ethereumjs-wallet";
|
|
|
28
27
|
const { thirdparty: importers } = $Wallet;
|
|
29
28
|
const Wallet = $importDefault($Wallet);
|
|
30
29
|
import $lodash from "lodash";
|
|
31
|
-
const { isEqual } = $lodash;
|
|
30
|
+
const { cloneDeep, isEqual } = $lodash;
|
|
32
31
|
// When generating a ULID within the same millisecond, monotonicFactory provides some guarantees regarding sort order.
|
|
33
32
|
import { ulid } from "ulid";
|
|
34
33
|
import { KeyringControllerError } from "./constants.mjs";
|
|
@@ -113,23 +112,6 @@ function assertHasUint8ArrayMnemonic(keyring) {
|
|
|
113
112
|
throw new Error("Can't get mnemonic bytes from keyring");
|
|
114
113
|
}
|
|
115
114
|
}
|
|
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
|
-
}
|
|
133
115
|
/**
|
|
134
116
|
* Assert that the provided password is a valid non-empty string.
|
|
135
117
|
*
|
|
@@ -231,12 +213,11 @@ export class KeyringController extends BaseController {
|
|
|
231
213
|
* @param options - Initial options used to configure this controller
|
|
232
214
|
* @param options.encryptor - An optional object for defining encryption schemes.
|
|
233
215
|
* @param options.keyringBuilders - Set a new name for account.
|
|
234
|
-
* @param options.cacheEncryptionKey - Whether to cache or not encryption key.
|
|
235
216
|
* @param options.messenger - A restricted messenger.
|
|
236
217
|
* @param options.state - Initial state to set on this controller.
|
|
237
218
|
*/
|
|
238
219
|
constructor(options) {
|
|
239
|
-
const { encryptor
|
|
220
|
+
const { encryptor, keyringBuilders, messenger, state } = options;
|
|
240
221
|
super({
|
|
241
222
|
name,
|
|
242
223
|
metadata: {
|
|
@@ -282,22 +263,15 @@ export class KeyringController extends BaseController {
|
|
|
282
263
|
_KeyringController_vaultOperationMutex.set(this, new Mutex());
|
|
283
264
|
_KeyringController_keyringBuilders.set(this, void 0);
|
|
284
265
|
_KeyringController_encryptor.set(this, void 0);
|
|
285
|
-
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
286
266
|
_KeyringController_keyrings.set(this, void 0);
|
|
287
267
|
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
288
|
-
|
|
268
|
+
_KeyringController_encryptionKey.set(this, void 0);
|
|
289
269
|
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
290
270
|
? keyringBuilders.concat(defaultKeyringBuilders)
|
|
291
271
|
: defaultKeyringBuilders, "f");
|
|
292
272
|
__classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
|
|
293
273
|
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
294
274
|
__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
|
-
}
|
|
301
275
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
|
|
302
276
|
}
|
|
303
277
|
/**
|
|
@@ -668,7 +642,7 @@ export class KeyringController extends BaseController {
|
|
|
668
642
|
async setLocked() {
|
|
669
643
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
670
644
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
671
|
-
__classPrivateFieldSet(this,
|
|
645
|
+
__classPrivateFieldSet(this, _KeyringController_encryptionKey, undefined, "f");
|
|
672
646
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
673
647
|
this.update((state) => {
|
|
674
648
|
state.isUnlocked = false;
|
|
@@ -850,22 +824,9 @@ export class KeyringController extends BaseController {
|
|
|
850
824
|
*/
|
|
851
825
|
changePassword(password) {
|
|
852
826
|
__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
|
-
}
|
|
857
827
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
858
828
|
assertIsValidPassword(password);
|
|
859
|
-
|
|
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
|
-
}
|
|
829
|
+
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password);
|
|
869
830
|
});
|
|
870
831
|
}
|
|
871
832
|
/**
|
|
@@ -874,12 +835,15 @@ export class KeyringController extends BaseController {
|
|
|
874
835
|
* consistency with the vault salt.
|
|
875
836
|
*
|
|
876
837
|
* @param encryptionKey - Key to unlock the keychain.
|
|
877
|
-
* @param
|
|
838
|
+
* @param keyDerivationSalt - Optional salt to unlock the keychain.
|
|
878
839
|
* @returns Promise resolving when the operation completes.
|
|
879
840
|
*/
|
|
880
|
-
async submitEncryptionKey(encryptionKey,
|
|
841
|
+
async submitEncryptionKey(encryptionKey, keyDerivationSalt) {
|
|
881
842
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
882
|
-
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this,
|
|
843
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, {
|
|
844
|
+
encryptionKey,
|
|
845
|
+
keyDerivationSalt,
|
|
846
|
+
});
|
|
883
847
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
884
848
|
return result;
|
|
885
849
|
});
|
|
@@ -906,9 +870,8 @@ export class KeyringController extends BaseController {
|
|
|
906
870
|
async exportEncryptionKey() {
|
|
907
871
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
908
872
|
return await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async () => {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
return encryptionKey;
|
|
873
|
+
assertIsEncryptionKeySet(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.serialized);
|
|
874
|
+
return __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").serialized;
|
|
912
875
|
});
|
|
913
876
|
}
|
|
914
877
|
/**
|
|
@@ -920,7 +883,7 @@ export class KeyringController extends BaseController {
|
|
|
920
883
|
*/
|
|
921
884
|
async submitPassword(password) {
|
|
922
885
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
923
|
-
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password);
|
|
886
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, { password });
|
|
924
887
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
925
888
|
return result;
|
|
926
889
|
});
|
|
@@ -930,6 +893,12 @@ export class KeyringController extends BaseController {
|
|
|
930
893
|
// can attempt to upgrade the vault.
|
|
931
894
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
932
895
|
if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
|
|
896
|
+
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
|
|
897
|
+
// If the vault is being upgraded, we want to ignore the metadata
|
|
898
|
+
// that is already in the vault, so we can effectively
|
|
899
|
+
// re-encrypt the vault with the new encryption config.
|
|
900
|
+
useVaultKeyMetadata: false,
|
|
901
|
+
});
|
|
933
902
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
|
|
934
903
|
}
|
|
935
904
|
});
|
|
@@ -991,7 +960,7 @@ export class KeyringController extends BaseController {
|
|
|
991
960
|
return keyring.type;
|
|
992
961
|
}
|
|
993
962
|
}
|
|
994
|
-
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(),
|
|
963
|
+
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(), _KeyringController_encryptionKey = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
|
|
995
964
|
this.messenger.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
996
965
|
this.messenger.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
|
|
997
966
|
this.messenger.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
@@ -1050,10 +1019,60 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
|
|
|
1050
1019
|
delete state.encryptionKey;
|
|
1051
1020
|
delete state.encryptionSalt;
|
|
1052
1021
|
});
|
|
1053
|
-
|
|
1022
|
+
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password);
|
|
1054
1023
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1055
1024
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
|
|
1056
1025
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
1026
|
+
}, _KeyringController_deriveEncryptionKey =
|
|
1027
|
+
/**
|
|
1028
|
+
* Derive the vault encryption key from the provided password, and
|
|
1029
|
+
* assign it to the instance variable for later use with cryptographic
|
|
1030
|
+
* functions.
|
|
1031
|
+
*
|
|
1032
|
+
* When the controller has a vault in its state, the key is derived
|
|
1033
|
+
* using the salt from the vault. If the vault is empty, a new salt
|
|
1034
|
+
* is generated and used to derive the key.
|
|
1035
|
+
*
|
|
1036
|
+
* @param password - The password to use for decryption or derivation.
|
|
1037
|
+
* @param options - Options for the key derivation.
|
|
1038
|
+
* @param options.useVaultKeyMetadata - Whether to use the vault key metadata
|
|
1039
|
+
*/
|
|
1040
|
+
async function _KeyringController_deriveEncryptionKey(password, options = {
|
|
1041
|
+
useVaultKeyMetadata: true,
|
|
1042
|
+
}) {
|
|
1043
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1044
|
+
const { vault } = this.state;
|
|
1045
|
+
if (typeof password !== 'string') {
|
|
1046
|
+
throw new TypeError(KeyringControllerError.WrongPasswordType);
|
|
1047
|
+
}
|
|
1048
|
+
let salt, keyMetadata;
|
|
1049
|
+
if (vault && options.useVaultKeyMetadata) {
|
|
1050
|
+
const parsedVault = JSON.parse(vault);
|
|
1051
|
+
salt = parsedVault.salt;
|
|
1052
|
+
keyMetadata = parsedVault.keyMetadata;
|
|
1053
|
+
}
|
|
1054
|
+
else {
|
|
1055
|
+
salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
|
|
1056
|
+
}
|
|
1057
|
+
const serializedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true, keyMetadata));
|
|
1058
|
+
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1059
|
+
salt,
|
|
1060
|
+
serialized: serializedEncryptionKey,
|
|
1061
|
+
}, "f");
|
|
1062
|
+
}, _KeyringController_setEncryptionKey = function _KeyringController_setEncryptionKey(encryptionKey, keyDerivationSalt) {
|
|
1063
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1064
|
+
if (typeof encryptionKey !== 'string' ||
|
|
1065
|
+
typeof keyDerivationSalt !== 'string') {
|
|
1066
|
+
throw new TypeError(KeyringControllerError.WrongEncryptionKeyType);
|
|
1067
|
+
}
|
|
1068
|
+
const { vault } = this.state;
|
|
1069
|
+
if (vault && JSON.parse(vault).salt !== keyDerivationSalt) {
|
|
1070
|
+
throw new Error(KeyringControllerError.ExpiredCredentials);
|
|
1071
|
+
}
|
|
1072
|
+
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1073
|
+
salt: keyDerivationSalt,
|
|
1074
|
+
serialized: encryptionKey,
|
|
1075
|
+
}, "f");
|
|
1057
1076
|
}, _KeyringController_verifySeedPhrase =
|
|
1058
1077
|
/**
|
|
1059
1078
|
* Internal non-exclusive method to verify the seed phrase.
|
|
@@ -1134,7 +1153,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1134
1153
|
return serializedKeyrings;
|
|
1135
1154
|
}, _KeyringController_getSessionState =
|
|
1136
1155
|
/**
|
|
1137
|
-
* Get a snapshot of session data held by
|
|
1156
|
+
* Get a snapshot of session data held by instance variables.
|
|
1138
1157
|
*
|
|
1139
1158
|
* @returns An object with serialized keyrings, keyrings metadata,
|
|
1140
1159
|
* and the user password.
|
|
@@ -1142,7 +1161,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1142
1161
|
async function _KeyringController_getSessionState() {
|
|
1143
1162
|
return {
|
|
1144
1163
|
keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
|
|
1145
|
-
|
|
1164
|
+
encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"),
|
|
1146
1165
|
};
|
|
1147
1166
|
}, _KeyringController_restoreSerializedKeyrings =
|
|
1148
1167
|
/**
|
|
@@ -1171,54 +1190,27 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
|
|
|
1171
1190
|
* Unlock Keyrings, decrypting the vault and deserializing all
|
|
1172
1191
|
* keyrings contained in it, using a password or an encryption key with salt.
|
|
1173
1192
|
*
|
|
1174
|
-
* @param
|
|
1175
|
-
* @param encryptionKey - An exported key string to unlock keyrings with.
|
|
1176
|
-
* @param encryptionSalt - The salt used to encrypt the vault.
|
|
1193
|
+
* @param credentials - The credentials to unlock the keyrings.
|
|
1177
1194
|
* @returns A promise resolving to the deserialized keyrings array.
|
|
1178
1195
|
*/
|
|
1179
|
-
async function _KeyringController_unlockKeyrings(
|
|
1196
|
+
async function _KeyringController_unlockKeyrings(credentials) {
|
|
1180
1197
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1181
|
-
|
|
1182
|
-
if (!encryptedVault) {
|
|
1198
|
+
if (!this.state.vault) {
|
|
1183
1199
|
throw new Error(KeyringControllerError.VaultError);
|
|
1184
1200
|
}
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
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
|
-
}
|
|
1201
|
+
const parsedEncryptedVault = JSON.parse(this.state.vault);
|
|
1202
|
+
if ('password' in credentials) {
|
|
1203
|
+
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, credentials.password);
|
|
1214
1204
|
}
|
|
1215
1205
|
else {
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1206
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setEncryptionKey).call(this, credentials.encryptionKey, credentials.keyDerivationSalt || parsedEncryptedVault.salt);
|
|
1207
|
+
}
|
|
1208
|
+
const encryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.serialized;
|
|
1209
|
+
if (!encryptionKey) {
|
|
1210
|
+
throw new Error(KeyringControllerError.MissingCredentials);
|
|
1221
1211
|
}
|
|
1212
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1213
|
+
const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1222
1214
|
if (!isSerializedKeyringsArray(vault)) {
|
|
1223
1215
|
throw new Error(KeyringControllerError.VaultDataError);
|
|
1224
1216
|
}
|
|
@@ -1226,10 +1218,8 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
|
|
|
1226
1218
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1227
1219
|
this.update((state) => {
|
|
1228
1220
|
state.keyrings = updatedKeyrings;
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
state.encryptionSalt = updatedState.encryptionSalt;
|
|
1232
|
-
}
|
|
1221
|
+
state.encryptionKey = encryptionKey;
|
|
1222
|
+
state.encryptionSalt = parsedEncryptedVault.salt;
|
|
1233
1223
|
});
|
|
1234
1224
|
return { keyrings, newMetadata };
|
|
1235
1225
|
});
|
|
@@ -1237,57 +1227,36 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
|
|
|
1237
1227
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1238
1228
|
// Ensure no duplicate accounts are persisted.
|
|
1239
1229
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this);
|
|
1240
|
-
|
|
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) {
|
|
1230
|
+
if (!__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")) {
|
|
1249
1231
|
throw new Error(KeyringControllerError.MissingCredentials);
|
|
1250
1232
|
}
|
|
1251
1233
|
const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1252
1234
|
if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
|
|
1253
1235
|
throw new Error(KeyringControllerError.NoHdKeyring);
|
|
1254
1236
|
}
|
|
1255
|
-
const
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
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
|
-
}
|
|
1237
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").serialized);
|
|
1238
|
+
const encryptedVault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
|
|
1239
|
+
// We need to include the salt used to derive
|
|
1240
|
+
// the encryption key, to be able to derive it
|
|
1241
|
+
// from password again.
|
|
1242
|
+
encryptedVault.salt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt;
|
|
1243
|
+
const updatedState = {
|
|
1244
|
+
vault: JSON.stringify(encryptedVault),
|
|
1245
|
+
encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").serialized,
|
|
1246
|
+
encryptionSalt: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt,
|
|
1247
|
+
};
|
|
1277
1248
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1278
1249
|
this.update((state) => {
|
|
1279
1250
|
state.vault = updatedState.vault;
|
|
1280
1251
|
state.keyrings = updatedKeyrings;
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
state.encryptionSalt = JSON.parse(updatedState.vault).salt;
|
|
1284
|
-
}
|
|
1252
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1253
|
+
state.encryptionSalt = updatedState.encryptionSalt;
|
|
1285
1254
|
});
|
|
1286
1255
|
return true;
|
|
1287
1256
|
});
|
|
1288
1257
|
}, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
|
|
1289
1258
|
const { vault } = this.state;
|
|
1290
|
-
if (!vault || !__classPrivateFieldGet(this,
|
|
1259
|
+
if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1291
1260
|
return false;
|
|
1292
1261
|
}
|
|
1293
1262
|
return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
|
|
@@ -1521,13 +1490,13 @@ async function _KeyringController_persistOrRollback(callback) {
|
|
|
1521
1490
|
async function _KeyringController_withRollback(callback) {
|
|
1522
1491
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
|
|
1523
1492
|
const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1524
|
-
const
|
|
1493
|
+
const currentEncryptionKey = cloneDeep(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"));
|
|
1525
1494
|
try {
|
|
1526
1495
|
return await callback({ releaseLock });
|
|
1527
1496
|
}
|
|
1528
1497
|
catch (e) {
|
|
1529
|
-
// Keyrings and
|
|
1530
|
-
__classPrivateFieldSet(this,
|
|
1498
|
+
// Keyrings and encryption credentials are restored to their previous state
|
|
1499
|
+
__classPrivateFieldSet(this, _KeyringController_encryptionKey, currentEncryptionKey, "f");
|
|
1531
1500
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
|
|
1532
1501
|
throw e;
|
|
1533
1502
|
}
|