@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
|
@@ -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;
|
|
@@ -28,7 +28,7 @@ import $Wallet from "ethereumjs-wallet";
|
|
|
28
28
|
const { thirdparty: importers } = $Wallet;
|
|
29
29
|
const Wallet = $importDefault($Wallet);
|
|
30
30
|
import $lodash from "lodash";
|
|
31
|
-
const {
|
|
31
|
+
const { isEqual } = $lodash;
|
|
32
32
|
// When generating a ULID within the same millisecond, monotonicFactory provides some guarantees regarding sort order.
|
|
33
33
|
import { ulid } from "ulid";
|
|
34
34
|
import { KeyringControllerError } from "./constants.mjs";
|
|
@@ -231,6 +231,7 @@ export class KeyringController extends BaseController {
|
|
|
231
231
|
* @param options - Initial options used to configure this controller
|
|
232
232
|
* @param options.encryptor - An optional object for defining encryption schemes.
|
|
233
233
|
* @param options.keyringBuilders - Set a new name for account.
|
|
234
|
+
* @param options.cacheEncryptionKey - Whether to cache or not encryption key.
|
|
234
235
|
* @param options.messenger - A restricted messenger.
|
|
235
236
|
* @param options.state - Initial state to set on this controller.
|
|
236
237
|
*/
|
|
@@ -281,16 +282,22 @@ export class KeyringController extends BaseController {
|
|
|
281
282
|
_KeyringController_vaultOperationMutex.set(this, new Mutex());
|
|
282
283
|
_KeyringController_keyringBuilders.set(this, void 0);
|
|
283
284
|
_KeyringController_encryptor.set(this, void 0);
|
|
285
|
+
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
284
286
|
_KeyringController_keyrings.set(this, void 0);
|
|
285
287
|
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
286
|
-
|
|
288
|
+
_KeyringController_password.set(this, void 0);
|
|
287
289
|
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
288
290
|
? keyringBuilders.concat(defaultKeyringBuilders)
|
|
289
291
|
: defaultKeyringBuilders, "f");
|
|
290
|
-
assertIsExportableKeyEncryptor(encryptor);
|
|
291
292
|
__classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
|
|
292
293
|
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
293
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
|
+
}
|
|
294
301
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
|
|
295
302
|
}
|
|
296
303
|
/**
|
|
@@ -661,7 +668,7 @@ export class KeyringController extends BaseController {
|
|
|
661
668
|
async setLocked() {
|
|
662
669
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
663
670
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
664
|
-
__classPrivateFieldSet(this,
|
|
671
|
+
__classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
|
|
665
672
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
666
673
|
this.update((state) => {
|
|
667
674
|
state.isUnlocked = false;
|
|
@@ -843,9 +850,22 @@ export class KeyringController extends BaseController {
|
|
|
843
850
|
*/
|
|
844
851
|
changePassword(password) {
|
|
845
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
|
+
}
|
|
846
857
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
847
858
|
assertIsValidPassword(password);
|
|
848
|
-
|
|
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
|
+
}
|
|
849
869
|
});
|
|
850
870
|
}
|
|
851
871
|
/**
|
|
@@ -854,15 +874,12 @@ export class KeyringController extends BaseController {
|
|
|
854
874
|
* consistency with the vault salt.
|
|
855
875
|
*
|
|
856
876
|
* @param encryptionKey - Key to unlock the keychain.
|
|
857
|
-
* @param
|
|
877
|
+
* @param encryptionSalt - Optional salt to unlock the keychain.
|
|
858
878
|
* @returns Promise resolving when the operation completes.
|
|
859
879
|
*/
|
|
860
|
-
async submitEncryptionKey(encryptionKey,
|
|
880
|
+
async submitEncryptionKey(encryptionKey, encryptionSalt) {
|
|
861
881
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
862
|
-
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this,
|
|
863
|
-
encryptionKey,
|
|
864
|
-
keyDerivationSalt,
|
|
865
|
-
});
|
|
882
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt);
|
|
866
883
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
867
884
|
return result;
|
|
868
885
|
});
|
|
@@ -889,8 +906,9 @@ export class KeyringController extends BaseController {
|
|
|
889
906
|
async exportEncryptionKey() {
|
|
890
907
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
891
908
|
return await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async () => {
|
|
892
|
-
|
|
893
|
-
|
|
909
|
+
const { encryptionKey } = this.state;
|
|
910
|
+
assertIsEncryptionKeySet(encryptionKey);
|
|
911
|
+
return encryptionKey;
|
|
894
912
|
});
|
|
895
913
|
}
|
|
896
914
|
/**
|
|
@@ -902,7 +920,7 @@ export class KeyringController extends BaseController {
|
|
|
902
920
|
*/
|
|
903
921
|
async submitPassword(password) {
|
|
904
922
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
905
|
-
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);
|
|
906
924
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
907
925
|
return result;
|
|
908
926
|
});
|
|
@@ -912,12 +930,6 @@ export class KeyringController extends BaseController {
|
|
|
912
930
|
// can attempt to upgrade the vault.
|
|
913
931
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
914
932
|
if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
|
|
915
|
-
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
|
|
916
|
-
// If the vault is being upgraded, we want to ignore the metadata
|
|
917
|
-
// that is already in the vault, so we can effectively
|
|
918
|
-
// re-encrypt the vault with the new encryption config.
|
|
919
|
-
useVaultKeyMetadata: false,
|
|
920
|
-
});
|
|
921
933
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
|
|
922
934
|
}
|
|
923
935
|
});
|
|
@@ -979,7 +991,7 @@ export class KeyringController extends BaseController {
|
|
|
979
991
|
return keyring.type;
|
|
980
992
|
}
|
|
981
993
|
}
|
|
982
|
-
_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() {
|
|
983
995
|
this.messenger.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
984
996
|
this.messenger.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
|
|
985
997
|
this.messenger.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
@@ -1038,60 +1050,10 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
|
|
|
1038
1050
|
delete state.encryptionKey;
|
|
1039
1051
|
delete state.encryptionSalt;
|
|
1040
1052
|
});
|
|
1041
|
-
|
|
1053
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1042
1054
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1043
1055
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
|
|
1044
1056
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
1045
|
-
}, _KeyringController_deriveEncryptionKey =
|
|
1046
|
-
/**
|
|
1047
|
-
* Derive the vault encryption key from the provided password, and
|
|
1048
|
-
* assign it to the instance variable for later use with cryptographic
|
|
1049
|
-
* functions.
|
|
1050
|
-
*
|
|
1051
|
-
* When the controller has a vault in its state, the key is derived
|
|
1052
|
-
* using the salt from the vault. If the vault is empty, a new salt
|
|
1053
|
-
* is generated and used to derive the key.
|
|
1054
|
-
*
|
|
1055
|
-
* @param password - The password to use for decryption or derivation.
|
|
1056
|
-
* @param options - Options for the key derivation.
|
|
1057
|
-
* @param options.useVaultKeyMetadata - Whether to use the vault key metadata
|
|
1058
|
-
*/
|
|
1059
|
-
async function _KeyringController_deriveEncryptionKey(password, options = {
|
|
1060
|
-
useVaultKeyMetadata: true,
|
|
1061
|
-
}) {
|
|
1062
|
-
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1063
|
-
const { vault } = this.state;
|
|
1064
|
-
if (typeof password !== 'string') {
|
|
1065
|
-
throw new TypeError(KeyringControllerError.WrongPasswordType);
|
|
1066
|
-
}
|
|
1067
|
-
let salt, keyMetadata;
|
|
1068
|
-
if (vault && options.useVaultKeyMetadata) {
|
|
1069
|
-
const parsedVault = JSON.parse(vault);
|
|
1070
|
-
salt = parsedVault.salt;
|
|
1071
|
-
keyMetadata = parsedVault.keyMetadata;
|
|
1072
|
-
}
|
|
1073
|
-
else {
|
|
1074
|
-
salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
|
|
1075
|
-
}
|
|
1076
|
-
const serializedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true, keyMetadata));
|
|
1077
|
-
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1078
|
-
salt,
|
|
1079
|
-
serialized: serializedEncryptionKey,
|
|
1080
|
-
}, "f");
|
|
1081
|
-
}, _KeyringController_setEncryptionKey = function _KeyringController_setEncryptionKey(encryptionKey, keyDerivationSalt) {
|
|
1082
|
-
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1083
|
-
if (typeof encryptionKey !== 'string' ||
|
|
1084
|
-
typeof keyDerivationSalt !== 'string') {
|
|
1085
|
-
throw new TypeError(KeyringControllerError.WrongEncryptionKeyType);
|
|
1086
|
-
}
|
|
1087
|
-
const { vault } = this.state;
|
|
1088
|
-
if (vault && JSON.parse(vault).salt !== keyDerivationSalt) {
|
|
1089
|
-
throw new Error(KeyringControllerError.ExpiredCredentials);
|
|
1090
|
-
}
|
|
1091
|
-
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1092
|
-
salt: keyDerivationSalt,
|
|
1093
|
-
serialized: encryptionKey,
|
|
1094
|
-
}, "f");
|
|
1095
1057
|
}, _KeyringController_verifySeedPhrase =
|
|
1096
1058
|
/**
|
|
1097
1059
|
* Internal non-exclusive method to verify the seed phrase.
|
|
@@ -1172,7 +1134,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1172
1134
|
return serializedKeyrings;
|
|
1173
1135
|
}, _KeyringController_getSessionState =
|
|
1174
1136
|
/**
|
|
1175
|
-
* Get a snapshot of session data held by
|
|
1137
|
+
* Get a snapshot of session data held by class variables.
|
|
1176
1138
|
*
|
|
1177
1139
|
* @returns An object with serialized keyrings, keyrings metadata,
|
|
1178
1140
|
* and the user password.
|
|
@@ -1180,7 +1142,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1180
1142
|
async function _KeyringController_getSessionState() {
|
|
1181
1143
|
return {
|
|
1182
1144
|
keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
|
|
1183
|
-
|
|
1145
|
+
password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
|
|
1184
1146
|
};
|
|
1185
1147
|
}, _KeyringController_restoreSerializedKeyrings =
|
|
1186
1148
|
/**
|
|
@@ -1209,27 +1171,54 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
|
|
|
1209
1171
|
* Unlock Keyrings, decrypting the vault and deserializing all
|
|
1210
1172
|
* keyrings contained in it, using a password or an encryption key with salt.
|
|
1211
1173
|
*
|
|
1212
|
-
* @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.
|
|
1213
1177
|
* @returns A promise resolving to the deserialized keyrings array.
|
|
1214
1178
|
*/
|
|
1215
|
-
async function _KeyringController_unlockKeyrings(
|
|
1179
|
+
async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
|
|
1216
1180
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1217
|
-
|
|
1181
|
+
const encryptedVault = this.state.vault;
|
|
1182
|
+
if (!encryptedVault) {
|
|
1218
1183
|
throw new Error(KeyringControllerError.VaultError);
|
|
1219
1184
|
}
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
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
|
+
}
|
|
1223
1214
|
}
|
|
1224
1215
|
else {
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
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");
|
|
1230
1221
|
}
|
|
1231
|
-
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1232
|
-
const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1233
1222
|
if (!isSerializedKeyringsArray(vault)) {
|
|
1234
1223
|
throw new Error(KeyringControllerError.VaultDataError);
|
|
1235
1224
|
}
|
|
@@ -1237,8 +1226,10 @@ async function _KeyringController_unlockKeyrings(credentials) {
|
|
|
1237
1226
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1238
1227
|
this.update((state) => {
|
|
1239
1228
|
state.keyrings = updatedKeyrings;
|
|
1240
|
-
|
|
1241
|
-
|
|
1229
|
+
if (updatedState.encryptionKey || updatedState.encryptionSalt) {
|
|
1230
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1231
|
+
state.encryptionSalt = updatedState.encryptionSalt;
|
|
1232
|
+
}
|
|
1242
1233
|
});
|
|
1243
1234
|
return { keyrings, newMetadata };
|
|
1244
1235
|
});
|
|
@@ -1246,36 +1237,57 @@ async function _KeyringController_unlockKeyrings(credentials) {
|
|
|
1246
1237
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1247
1238
|
// Ensure no duplicate accounts are persisted.
|
|
1248
1239
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this);
|
|
1249
|
-
|
|
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) {
|
|
1250
1249
|
throw new Error(KeyringControllerError.MissingCredentials);
|
|
1251
1250
|
}
|
|
1252
1251
|
const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1253
1252
|
if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
|
|
1254
1253
|
throw new Error(KeyringControllerError.NoHdKeyring);
|
|
1255
1254
|
}
|
|
1256
|
-
const
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
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
|
+
}
|
|
1267
1277
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1268
1278
|
this.update((state) => {
|
|
1269
1279
|
state.vault = updatedState.vault;
|
|
1270
1280
|
state.keyrings = updatedKeyrings;
|
|
1271
|
-
|
|
1272
|
-
|
|
1281
|
+
if (updatedState.encryptionKey) {
|
|
1282
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1283
|
+
state.encryptionSalt = JSON.parse(updatedState.vault).salt;
|
|
1284
|
+
}
|
|
1273
1285
|
});
|
|
1274
1286
|
return true;
|
|
1275
1287
|
});
|
|
1276
1288
|
}, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
|
|
1277
1289
|
const { vault } = this.state;
|
|
1278
|
-
if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1290
|
+
if (!vault || !__classPrivateFieldGet(this, _KeyringController_password, "f") || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1279
1291
|
return false;
|
|
1280
1292
|
}
|
|
1281
1293
|
return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
|
|
@@ -1509,13 +1521,13 @@ async function _KeyringController_persistOrRollback(callback) {
|
|
|
1509
1521
|
async function _KeyringController_withRollback(callback) {
|
|
1510
1522
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
|
|
1511
1523
|
const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1512
|
-
const
|
|
1524
|
+
const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
|
|
1513
1525
|
try {
|
|
1514
1526
|
return await callback({ releaseLock });
|
|
1515
1527
|
}
|
|
1516
1528
|
catch (e) {
|
|
1517
|
-
// Keyrings and
|
|
1518
|
-
__classPrivateFieldSet(this,
|
|
1529
|
+
// Keyrings and password are restored to their previous state
|
|
1530
|
+
__classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
|
|
1519
1531
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
|
|
1520
1532
|
throw e;
|
|
1521
1533
|
}
|