@metamask-previews/keyring-controller 24.0.0-preview-e2a66c7a → 24.0.0-preview-cb2e5c04
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 +21 -0
- package/dist/KeyringController.cjs +117 -135
- package/dist/KeyringController.cjs.map +1 -1
- package/dist/KeyringController.d.cts +49 -29
- package/dist/KeyringController.d.cts.map +1 -1
- package/dist/KeyringController.d.mts +49 -29
- package/dist/KeyringController.d.mts.map +1 -1
- package/dist/KeyringController.mjs +118 -136
- 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 +1 -1
|
@@ -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
|
*
|
|
@@ -236,7 +218,7 @@ export class KeyringController extends BaseController {
|
|
|
236
218
|
* @param options.state - Initial state to set on this controller.
|
|
237
219
|
*/
|
|
238
220
|
constructor(options) {
|
|
239
|
-
const { encryptor
|
|
221
|
+
const { encryptor, keyringBuilders, messenger, state } = options;
|
|
240
222
|
super({
|
|
241
223
|
name,
|
|
242
224
|
metadata: {
|
|
@@ -282,22 +264,15 @@ export class KeyringController extends BaseController {
|
|
|
282
264
|
_KeyringController_vaultOperationMutex.set(this, new Mutex());
|
|
283
265
|
_KeyringController_keyringBuilders.set(this, void 0);
|
|
284
266
|
_KeyringController_encryptor.set(this, void 0);
|
|
285
|
-
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
286
267
|
_KeyringController_keyrings.set(this, void 0);
|
|
287
268
|
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
288
|
-
|
|
269
|
+
_KeyringController_encryptionKey.set(this, void 0);
|
|
289
270
|
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
290
271
|
? keyringBuilders.concat(defaultKeyringBuilders)
|
|
291
272
|
: defaultKeyringBuilders, "f");
|
|
292
273
|
__classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
|
|
293
274
|
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
294
275
|
__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
276
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
|
|
302
277
|
}
|
|
303
278
|
/**
|
|
@@ -668,7 +643,7 @@ export class KeyringController extends BaseController {
|
|
|
668
643
|
async setLocked() {
|
|
669
644
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
670
645
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
671
|
-
__classPrivateFieldSet(this,
|
|
646
|
+
__classPrivateFieldSet(this, _KeyringController_encryptionKey, undefined, "f");
|
|
672
647
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
673
648
|
this.update((state) => {
|
|
674
649
|
state.isUnlocked = false;
|
|
@@ -850,22 +825,11 @@ export class KeyringController extends BaseController {
|
|
|
850
825
|
*/
|
|
851
826
|
changePassword(password) {
|
|
852
827
|
__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
828
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
858
829
|
assertIsValidPassword(password);
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
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
|
-
}
|
|
830
|
+
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
|
|
831
|
+
ignoreExistingVault: true,
|
|
832
|
+
});
|
|
869
833
|
});
|
|
870
834
|
}
|
|
871
835
|
/**
|
|
@@ -879,7 +843,10 @@ export class KeyringController extends BaseController {
|
|
|
879
843
|
*/
|
|
880
844
|
async submitEncryptionKey(encryptionKey, encryptionSalt) {
|
|
881
845
|
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,
|
|
846
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, {
|
|
847
|
+
encryptionKey,
|
|
848
|
+
encryptionSalt,
|
|
849
|
+
});
|
|
883
850
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
884
851
|
return result;
|
|
885
852
|
});
|
|
@@ -906,9 +873,8 @@ export class KeyringController extends BaseController {
|
|
|
906
873
|
async exportEncryptionKey() {
|
|
907
874
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
908
875
|
return await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async () => {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
return encryptionKey;
|
|
876
|
+
assertIsEncryptionKeySet(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.serialized);
|
|
877
|
+
return __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").serialized;
|
|
912
878
|
});
|
|
913
879
|
}
|
|
914
880
|
/**
|
|
@@ -920,7 +886,7 @@ export class KeyringController extends BaseController {
|
|
|
920
886
|
*/
|
|
921
887
|
async submitPassword(password) {
|
|
922
888
|
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);
|
|
889
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, { password });
|
|
924
890
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
925
891
|
return result;
|
|
926
892
|
});
|
|
@@ -930,6 +896,12 @@ export class KeyringController extends BaseController {
|
|
|
930
896
|
// can attempt to upgrade the vault.
|
|
931
897
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
932
898
|
if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
|
|
899
|
+
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
|
|
900
|
+
// If the vault is being upgraded, we want to ignore the metadata
|
|
901
|
+
// that is already in the vault, so we can effectively
|
|
902
|
+
// re-encrypt the vault with the new encryption config.
|
|
903
|
+
ignoreExistingVault: true,
|
|
904
|
+
});
|
|
933
905
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
|
|
934
906
|
}
|
|
935
907
|
});
|
|
@@ -991,7 +963,7 @@ export class KeyringController extends BaseController {
|
|
|
991
963
|
return keyring.type;
|
|
992
964
|
}
|
|
993
965
|
}
|
|
994
|
-
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(),
|
|
966
|
+
_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
967
|
this.messenger.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
996
968
|
this.messenger.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
|
|
997
969
|
this.messenger.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
@@ -1050,10 +1022,70 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
|
|
|
1050
1022
|
delete state.encryptionKey;
|
|
1051
1023
|
delete state.encryptionSalt;
|
|
1052
1024
|
});
|
|
1053
|
-
|
|
1025
|
+
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
|
|
1026
|
+
ignoreExistingVault: true,
|
|
1027
|
+
});
|
|
1054
1028
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1055
1029
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
|
|
1056
1030
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
1031
|
+
}, _KeyringController_deriveEncryptionKey =
|
|
1032
|
+
/**
|
|
1033
|
+
* Derive the vault encryption key from the provided password, and
|
|
1034
|
+
* assign it to the instance variable for later use with cryptographic
|
|
1035
|
+
* functions.
|
|
1036
|
+
*
|
|
1037
|
+
* When the controller has a vault in its state, the key is derived
|
|
1038
|
+
* using the salt from the vault. If the vault is empty, a new salt
|
|
1039
|
+
* is generated and used to derive the key.
|
|
1040
|
+
*
|
|
1041
|
+
* If `options.ignoreExistingVault` is set to `false`, the existing
|
|
1042
|
+
* vault is completely ignored: the new key won't be able to decrypt
|
|
1043
|
+
* the existing vault, and should be used to re-encrypt it.
|
|
1044
|
+
*
|
|
1045
|
+
* @param password - The password to use for decryption or derivation.
|
|
1046
|
+
* @param options - Options for the key derivation.
|
|
1047
|
+
* @param options.ignoreExistingVault - Whether to use the existing vault salt and key metadata
|
|
1048
|
+
*/
|
|
1049
|
+
async function _KeyringController_deriveEncryptionKey(password, options = {
|
|
1050
|
+
ignoreExistingVault: false,
|
|
1051
|
+
}) {
|
|
1052
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1053
|
+
const { vault } = this.state;
|
|
1054
|
+
if (typeof password !== 'string') {
|
|
1055
|
+
throw new TypeError(KeyringControllerError.WrongPasswordType);
|
|
1056
|
+
}
|
|
1057
|
+
let serializedEncryptionKey, salt;
|
|
1058
|
+
if (vault && !options.ignoreExistingVault) {
|
|
1059
|
+
// The `decryptWithDetail` method is being used here instead of
|
|
1060
|
+
// `keyFromPassword` + `exportKey` to let the encryptor handle
|
|
1061
|
+
// any legacy encryption formats and metadata that might be
|
|
1062
|
+
// present (or absent) in the vault.
|
|
1063
|
+
const { exportedKeyString, salt: existingSalt } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, vault);
|
|
1064
|
+
serializedEncryptionKey = exportedKeyString;
|
|
1065
|
+
salt = existingSalt;
|
|
1066
|
+
}
|
|
1067
|
+
else {
|
|
1068
|
+
salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
|
|
1069
|
+
serializedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true));
|
|
1070
|
+
}
|
|
1071
|
+
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1072
|
+
salt,
|
|
1073
|
+
serialized: serializedEncryptionKey,
|
|
1074
|
+
}, "f");
|
|
1075
|
+
}, _KeyringController_setEncryptionKey = function _KeyringController_setEncryptionKey(encryptionKey, keyDerivationSalt) {
|
|
1076
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1077
|
+
if (typeof encryptionKey !== 'string' ||
|
|
1078
|
+
typeof keyDerivationSalt !== 'string') {
|
|
1079
|
+
throw new TypeError(KeyringControllerError.WrongEncryptionKeyType);
|
|
1080
|
+
}
|
|
1081
|
+
const { vault } = this.state;
|
|
1082
|
+
if (vault && JSON.parse(vault).salt !== keyDerivationSalt) {
|
|
1083
|
+
throw new Error(KeyringControllerError.ExpiredCredentials);
|
|
1084
|
+
}
|
|
1085
|
+
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1086
|
+
salt: keyDerivationSalt,
|
|
1087
|
+
serialized: encryptionKey,
|
|
1088
|
+
}, "f");
|
|
1057
1089
|
}, _KeyringController_verifySeedPhrase =
|
|
1058
1090
|
/**
|
|
1059
1091
|
* Internal non-exclusive method to verify the seed phrase.
|
|
@@ -1134,7 +1166,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1134
1166
|
return serializedKeyrings;
|
|
1135
1167
|
}, _KeyringController_getSessionState =
|
|
1136
1168
|
/**
|
|
1137
|
-
* Get a snapshot of session data held by
|
|
1169
|
+
* Get a snapshot of session data held by instance variables.
|
|
1138
1170
|
*
|
|
1139
1171
|
* @returns An object with serialized keyrings, keyrings metadata,
|
|
1140
1172
|
* and the user password.
|
|
@@ -1142,7 +1174,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1142
1174
|
async function _KeyringController_getSessionState() {
|
|
1143
1175
|
return {
|
|
1144
1176
|
keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
|
|
1145
|
-
|
|
1177
|
+
encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"),
|
|
1146
1178
|
};
|
|
1147
1179
|
}, _KeyringController_restoreSerializedKeyrings =
|
|
1148
1180
|
/**
|
|
@@ -1171,54 +1203,27 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
|
|
|
1171
1203
|
* Unlock Keyrings, decrypting the vault and deserializing all
|
|
1172
1204
|
* keyrings contained in it, using a password or an encryption key with salt.
|
|
1173
1205
|
*
|
|
1174
|
-
* @param
|
|
1175
|
-
* @param encryptionKey - An exported key string to unlock keyrings with.
|
|
1176
|
-
* @param encryptionSalt - The salt used to encrypt the vault.
|
|
1206
|
+
* @param credentials - The credentials to unlock the keyrings.
|
|
1177
1207
|
* @returns A promise resolving to the deserialized keyrings array.
|
|
1178
1208
|
*/
|
|
1179
|
-
async function _KeyringController_unlockKeyrings(
|
|
1209
|
+
async function _KeyringController_unlockKeyrings(credentials) {
|
|
1180
1210
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1181
|
-
|
|
1182
|
-
if (!encryptedVault) {
|
|
1211
|
+
if (!this.state.vault) {
|
|
1183
1212
|
throw new Error(KeyringControllerError.VaultError);
|
|
1184
1213
|
}
|
|
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
|
-
}
|
|
1214
|
+
const parsedEncryptedVault = JSON.parse(this.state.vault);
|
|
1215
|
+
if ('password' in credentials) {
|
|
1216
|
+
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, credentials.password);
|
|
1214
1217
|
}
|
|
1215
1218
|
else {
|
|
1216
|
-
|
|
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");
|
|
1219
|
+
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setEncryptionKey).call(this, credentials.encryptionKey, credentials.encryptionSalt || parsedEncryptedVault.salt);
|
|
1221
1220
|
}
|
|
1221
|
+
const encryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.serialized;
|
|
1222
|
+
if (!encryptionKey) {
|
|
1223
|
+
throw new Error(KeyringControllerError.MissingCredentials);
|
|
1224
|
+
}
|
|
1225
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1226
|
+
const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1222
1227
|
if (!isSerializedKeyringsArray(vault)) {
|
|
1223
1228
|
throw new Error(KeyringControllerError.VaultDataError);
|
|
1224
1229
|
}
|
|
@@ -1226,10 +1231,8 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
|
|
|
1226
1231
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1227
1232
|
this.update((state) => {
|
|
1228
1233
|
state.keyrings = updatedKeyrings;
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
state.encryptionSalt = updatedState.encryptionSalt;
|
|
1232
|
-
}
|
|
1234
|
+
state.encryptionKey = encryptionKey;
|
|
1235
|
+
state.encryptionSalt = parsedEncryptedVault.salt;
|
|
1233
1236
|
});
|
|
1234
1237
|
return { keyrings, newMetadata };
|
|
1235
1238
|
});
|
|
@@ -1237,57 +1240,36 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
|
|
|
1237
1240
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1238
1241
|
// Ensure no duplicate accounts are persisted.
|
|
1239
1242
|
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) {
|
|
1243
|
+
if (!__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")) {
|
|
1249
1244
|
throw new Error(KeyringControllerError.MissingCredentials);
|
|
1250
1245
|
}
|
|
1251
1246
|
const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1252
1247
|
if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
|
|
1253
1248
|
throw new Error(KeyringControllerError.NoHdKeyring);
|
|
1254
1249
|
}
|
|
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
|
-
}
|
|
1250
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").serialized);
|
|
1251
|
+
const encryptedVault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
|
|
1252
|
+
// We need to include the salt used to derive
|
|
1253
|
+
// the encryption key, to be able to derive it
|
|
1254
|
+
// from password again.
|
|
1255
|
+
encryptedVault.salt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt;
|
|
1256
|
+
const updatedState = {
|
|
1257
|
+
vault: JSON.stringify(encryptedVault),
|
|
1258
|
+
encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").serialized,
|
|
1259
|
+
encryptionSalt: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt,
|
|
1260
|
+
};
|
|
1277
1261
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1278
1262
|
this.update((state) => {
|
|
1279
1263
|
state.vault = updatedState.vault;
|
|
1280
1264
|
state.keyrings = updatedKeyrings;
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
state.encryptionSalt = JSON.parse(updatedState.vault).salt;
|
|
1284
|
-
}
|
|
1265
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1266
|
+
state.encryptionSalt = updatedState.encryptionSalt;
|
|
1285
1267
|
});
|
|
1286
1268
|
return true;
|
|
1287
1269
|
});
|
|
1288
1270
|
}, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
|
|
1289
1271
|
const { vault } = this.state;
|
|
1290
|
-
if (!vault || !__classPrivateFieldGet(this,
|
|
1272
|
+
if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1291
1273
|
return false;
|
|
1292
1274
|
}
|
|
1293
1275
|
return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
|
|
@@ -1521,13 +1503,13 @@ async function _KeyringController_persistOrRollback(callback) {
|
|
|
1521
1503
|
async function _KeyringController_withRollback(callback) {
|
|
1522
1504
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
|
|
1523
1505
|
const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1524
|
-
const
|
|
1506
|
+
const currentEncryptionKey = cloneDeep(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"));
|
|
1525
1507
|
try {
|
|
1526
1508
|
return await callback({ releaseLock });
|
|
1527
1509
|
}
|
|
1528
1510
|
catch (e) {
|
|
1529
|
-
// Keyrings and
|
|
1530
|
-
__classPrivateFieldSet(this,
|
|
1511
|
+
// Keyrings and encryption credentials are restored to their previous state
|
|
1512
|
+
__classPrivateFieldSet(this, _KeyringController_encryptionKey, currentEncryptionKey, "f");
|
|
1531
1513
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
|
|
1532
1514
|
throw e;
|
|
1533
1515
|
}
|