@metamask-previews/keyring-controller 22.0.2-preview-13f36eb8 → 22.0.2-preview-7a575715
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 -16
- package/dist/KeyringController.cjs +109 -103
- package/dist/KeyringController.cjs.map +1 -1
- package/dist/KeyringController.d.cts +9 -24
- package/dist/KeyringController.d.cts.map +1 -1
- package/dist/KeyringController.d.mts +9 -24
- package/dist/KeyringController.d.mts.map +1 -1
- package/dist/KeyringController.mjs +109 -103
- package/dist/KeyringController.mjs.map +1 -1
- package/dist/constants.cjs +0 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +0 -1
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +0 -1
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +0 -1
- package/dist/constants.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,22 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
### Added
|
|
11
|
-
|
|
12
|
-
- Added optional `SupportedKeyDerivationOptions` type parameter to the `ExportableKeyEncryptor` type ([#5963](https://github.com/MetaMask/core/pull/5963))
|
|
13
|
-
- This type parameter allows specifying the key derivation options supported by the injected encryptor.
|
|
14
|
-
|
|
15
|
-
### Changed
|
|
16
|
-
|
|
17
|
-
- **BREAKING:** The `KeyringController` constructor now requires an encryptor supporting the `keyFromPassword`, `exportKey` and `generateSalt` methods ([#5963](https://github.com/MetaMask/core/pull/5963))
|
|
18
|
-
|
|
19
|
-
### Removed
|
|
20
|
-
|
|
21
|
-
- **BREAKING:** The `cacheEncryptionKey` parameter has been removed from the `KeyringController` constructor options ([#5963](https://github.com/MetaMask/core/pull/5963))
|
|
22
|
-
- This parameter was previously used to enable encryption key in-memory caching, but it is no longer needed as the controller now always uses the latest encryption key.
|
|
23
|
-
- **BREAKING:** The `submitEncryptionKey` method does not accept an `encryptionSalt` argument anymore ([#5963](https://github.com/MetaMask/core/pull/5963))
|
|
24
|
-
- The encryption salt is now always taken from the vault.
|
|
25
|
-
|
|
26
10
|
## [22.0.2]
|
|
27
11
|
|
|
28
12
|
### Fixed
|
|
@@ -36,7 +36,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
36
36
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
37
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
38
|
};
|
|
39
|
-
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings,
|
|
39
|
+
var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_cacheEncryptionKey, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_password, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_verifySeedPhrase, _KeyringController_getUpdatedKeyrings, _KeyringController_getSerializedKeyrings, _KeyringController_getSessionState, _KeyringController_restoreSerializedKeyrings, _KeyringController_unlockKeyrings, _KeyringController_updateVault, _KeyringController_isNewEncryptionAvailable, _KeyringController_getAccountsFromKeyrings, _KeyringController_createKeyringWithFirstAccount, _KeyringController_newKeyring, _KeyringController_createKeyring, _KeyringController_clearKeyrings, _KeyringController_restoreKeyring, _KeyringController_destroyKeyring, _KeyringController_removeEmptyKeyrings, _KeyringController_assertNoDuplicateAccounts, _KeyringController_setUnlocked, _KeyringController_assertIsUnlocked, _KeyringController_persistOrRollback, _KeyringController_withRollback, _KeyringController_assertControllerMutexIsLocked, _KeyringController_withControllerLock, _KeyringController_withVaultLock;
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
41
|
exports.KeyringController = exports.getDefaultKeyringState = exports.keyringBuilderFactory = exports.SignTypedDataVersion = exports.AccountImportStrategy = exports.isCustodyKeyring = exports.KeyringTypes = void 0;
|
|
42
42
|
const util_1 = require("@ethereumjs/util");
|
|
@@ -270,17 +270,23 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
270
270
|
_KeyringController_vaultOperationMutex.set(this, new async_mutex_1.Mutex());
|
|
271
271
|
_KeyringController_keyringBuilders.set(this, void 0);
|
|
272
272
|
_KeyringController_encryptor.set(this, void 0);
|
|
273
|
+
_KeyringController_cacheEncryptionKey.set(this, void 0);
|
|
273
274
|
_KeyringController_keyrings.set(this, void 0);
|
|
274
275
|
_KeyringController_unsupportedKeyrings.set(this, void 0);
|
|
275
|
-
|
|
276
|
+
_KeyringController_password.set(this, void 0);
|
|
276
277
|
_KeyringController_qrKeyringStateListener.set(this, void 0);
|
|
277
278
|
__classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
|
|
278
279
|
? keyringBuilders.concat(defaultKeyringBuilders)
|
|
279
280
|
: defaultKeyringBuilders, "f");
|
|
280
|
-
assertIsExportableKeyEncryptor(encryptor);
|
|
281
281
|
__classPrivateFieldSet(this, _KeyringController_encryptor, encryptor, "f");
|
|
282
282
|
__classPrivateFieldSet(this, _KeyringController_keyrings, [], "f");
|
|
283
283
|
__classPrivateFieldSet(this, _KeyringController_unsupportedKeyrings, [], "f");
|
|
284
|
+
// This option allows the controller to cache an exported key
|
|
285
|
+
// for use in decrypting and encrypting data without password
|
|
286
|
+
__classPrivateFieldSet(this, _KeyringController_cacheEncryptionKey, Boolean(options.cacheEncryptionKey), "f");
|
|
287
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
288
|
+
assertIsExportableKeyEncryptor(encryptor);
|
|
289
|
+
}
|
|
284
290
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
|
|
285
291
|
}
|
|
286
292
|
/**
|
|
@@ -655,7 +661,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
655
661
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
656
662
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
657
663
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unsubscribeFromQRKeyringsEvents).call(this);
|
|
658
|
-
__classPrivateFieldSet(this,
|
|
664
|
+
__classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
|
|
659
665
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
660
666
|
this.update((state) => {
|
|
661
667
|
state.isUnlocked = false;
|
|
@@ -839,7 +845,16 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
839
845
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
|
|
840
846
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
|
|
841
847
|
assertIsValidPassword(password);
|
|
842
|
-
|
|
848
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
849
|
+
// We need to clear encryption key and salt from state
|
|
850
|
+
// to force the controller to re-encrypt the vault using
|
|
851
|
+
// the new password.
|
|
852
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
853
|
+
this.update((state) => {
|
|
854
|
+
delete state.encryptionKey;
|
|
855
|
+
delete state.encryptionSalt;
|
|
856
|
+
});
|
|
857
|
+
}
|
|
843
858
|
});
|
|
844
859
|
}
|
|
845
860
|
/**
|
|
@@ -847,13 +862,12 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
847
862
|
* using the given encryption key and salt.
|
|
848
863
|
*
|
|
849
864
|
* @param encryptionKey - Key to unlock the keychain.
|
|
865
|
+
* @param encryptionSalt - Salt to unlock the keychain.
|
|
850
866
|
* @returns Promise resolving when the operation completes.
|
|
851
867
|
*/
|
|
852
|
-
async submitEncryptionKey(encryptionKey) {
|
|
868
|
+
async submitEncryptionKey(encryptionKey, encryptionSalt) {
|
|
853
869
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
854
|
-
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this,
|
|
855
|
-
exportedEncryptionKey: encryptionKey,
|
|
856
|
-
});
|
|
870
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt);
|
|
857
871
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
858
872
|
return result;
|
|
859
873
|
});
|
|
@@ -881,7 +895,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
881
895
|
*/
|
|
882
896
|
async submitPassword(password) {
|
|
883
897
|
const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
884
|
-
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this,
|
|
898
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password);
|
|
885
899
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
886
900
|
return result;
|
|
887
901
|
});
|
|
@@ -891,12 +905,6 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
891
905
|
// can attempt to upgrade the vault.
|
|
892
906
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
|
|
893
907
|
if (newMetadata || __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_isNewEncryptionAvailable).call(this)) {
|
|
894
|
-
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password, {
|
|
895
|
-
// If the vault is being upgraded, we want to ignore the metadata
|
|
896
|
-
// that is already in the vault, so we can effectively
|
|
897
|
-
// re-encrypt the vault with the new encryption config.
|
|
898
|
-
ignoreVaultKeyMetadata: true,
|
|
899
|
-
});
|
|
900
908
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
|
|
901
909
|
}
|
|
902
910
|
});
|
|
@@ -1151,7 +1159,7 @@ class KeyringController extends base_controller_1.BaseController {
|
|
|
1151
1159
|
}
|
|
1152
1160
|
}
|
|
1153
1161
|
exports.KeyringController = KeyringController;
|
|
1154
|
-
_KeyringController_controllerOperationMutex = new WeakMap(), _KeyringController_vaultOperationMutex = new WeakMap(), _KeyringController_keyringBuilders = new WeakMap(), _KeyringController_encryptor = new WeakMap(), _KeyringController_keyrings = new WeakMap(), _KeyringController_unsupportedKeyrings = new WeakMap(),
|
|
1162
|
+
_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_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
|
|
1155
1163
|
this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
|
|
1156
1164
|
this.messagingSystem.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
|
|
1157
1165
|
this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
|
|
@@ -1231,56 +1239,10 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
|
|
|
1231
1239
|
delete state.encryptionKey;
|
|
1232
1240
|
delete state.encryptionSalt;
|
|
1233
1241
|
});
|
|
1234
|
-
|
|
1242
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1235
1243
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
|
|
1236
1244
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
|
|
1237
1245
|
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
|
|
1238
|
-
}, _KeyringController_deriveEncryptionKey =
|
|
1239
|
-
/**
|
|
1240
|
-
* Derive the vault encryption key from the provided password, and
|
|
1241
|
-
* assign it to the class variable for later use with cryptographic
|
|
1242
|
-
* functions.
|
|
1243
|
-
*
|
|
1244
|
-
* When the controller has a vault in its state, the key is derived
|
|
1245
|
-
* using the salt from the vault. If the vault is empty, a new salt
|
|
1246
|
-
* is generated and used to derive the key.
|
|
1247
|
-
*
|
|
1248
|
-
* @param password - The password to use for decryption or derivation.
|
|
1249
|
-
* @param options - Options for the key derivation.
|
|
1250
|
-
* @param options.ignoreVaultKeyMetadata - Whether to ignore the vault key metadata
|
|
1251
|
-
*/
|
|
1252
|
-
async function _KeyringController_deriveEncryptionKey(password, options = {
|
|
1253
|
-
ignoreVaultKeyMetadata: false,
|
|
1254
|
-
}) {
|
|
1255
|
-
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1256
|
-
const { vault } = this.state;
|
|
1257
|
-
if (typeof password !== 'string') {
|
|
1258
|
-
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1259
|
-
}
|
|
1260
|
-
let salt, keyMetadata;
|
|
1261
|
-
if (vault && !options.ignoreVaultKeyMetadata) {
|
|
1262
|
-
const parsedVault = JSON.parse(vault);
|
|
1263
|
-
salt = parsedVault.salt;
|
|
1264
|
-
keyMetadata = parsedVault.keyMetadata;
|
|
1265
|
-
}
|
|
1266
|
-
else {
|
|
1267
|
-
salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
|
|
1268
|
-
}
|
|
1269
|
-
const exportedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true, keyMetadata));
|
|
1270
|
-
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1271
|
-
salt,
|
|
1272
|
-
exported: exportedEncryptionKey,
|
|
1273
|
-
}, "f");
|
|
1274
|
-
}, _KeyringController_useEncryptionKey = function _KeyringController_useEncryptionKey(encryptionKey, encryptionSalt) {
|
|
1275
|
-
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
|
|
1276
|
-
if (typeof encryptionKey !== 'string' ||
|
|
1277
|
-
typeof encryptionSalt !== 'string') {
|
|
1278
|
-
throw new TypeError(constants_1.KeyringControllerError.WrongEncryptionKeyType);
|
|
1279
|
-
}
|
|
1280
|
-
__classPrivateFieldSet(this, _KeyringController_encryptionKey, {
|
|
1281
|
-
salt: encryptionSalt,
|
|
1282
|
-
exported: encryptionKey,
|
|
1283
|
-
}, "f");
|
|
1284
1246
|
}, _KeyringController_verifySeedPhrase =
|
|
1285
1247
|
/**
|
|
1286
1248
|
* Internal non-exclusive method to verify the seed phrase.
|
|
@@ -1369,7 +1331,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
|
|
|
1369
1331
|
async function _KeyringController_getSessionState() {
|
|
1370
1332
|
return {
|
|
1371
1333
|
keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
|
|
1372
|
-
|
|
1334
|
+
password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
|
|
1373
1335
|
};
|
|
1374
1336
|
}, _KeyringController_restoreSerializedKeyrings =
|
|
1375
1337
|
/**
|
|
@@ -1398,28 +1360,54 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
|
|
|
1398
1360
|
* Unlock Keyrings, decrypting the vault and deserializing all
|
|
1399
1361
|
* keyrings contained in it, using a password or an encryption key with salt.
|
|
1400
1362
|
*
|
|
1401
|
-
* @param
|
|
1363
|
+
* @param password - The keyring controller password.
|
|
1364
|
+
* @param encryptionKey - An exported key string to unlock keyrings with.
|
|
1365
|
+
* @param encryptionSalt - The salt used to encrypt the vault.
|
|
1402
1366
|
* @returns A promise resolving to the deserialized keyrings array.
|
|
1403
1367
|
*/
|
|
1404
|
-
async function _KeyringController_unlockKeyrings(
|
|
1368
|
+
async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
|
|
1405
1369
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1406
|
-
|
|
1370
|
+
const encryptedVault = this.state.vault;
|
|
1371
|
+
if (!encryptedVault) {
|
|
1407
1372
|
throw new Error(constants_1.KeyringControllerError.VaultError);
|
|
1408
1373
|
}
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1374
|
+
let vault;
|
|
1375
|
+
const updatedState = {};
|
|
1376
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
1377
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
1378
|
+
if (password) {
|
|
1379
|
+
const result = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithDetail(password, encryptedVault);
|
|
1380
|
+
vault = result.vault;
|
|
1381
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1382
|
+
updatedState.encryptionKey = result.exportedKeyString;
|
|
1383
|
+
updatedState.encryptionSalt = result.salt;
|
|
1384
|
+
}
|
|
1385
|
+
else {
|
|
1386
|
+
const parsedEncryptedVault = JSON.parse(encryptedVault);
|
|
1387
|
+
if (encryptionSalt !== parsedEncryptedVault.salt) {
|
|
1388
|
+
throw new Error(constants_1.KeyringControllerError.ExpiredCredentials);
|
|
1389
|
+
}
|
|
1390
|
+
if (typeof encryptionKey !== 'string') {
|
|
1391
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1392
|
+
}
|
|
1393
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1394
|
+
vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1395
|
+
// This call is required on the first call because encryptionKey
|
|
1396
|
+
// is not yet inside the memStore
|
|
1397
|
+
updatedState.encryptionKey = encryptionKey;
|
|
1398
|
+
// we can safely assume that encryptionSalt is defined here
|
|
1399
|
+
// because we compare it with the salt from the vault
|
|
1400
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1401
|
+
updatedState.encryptionSalt = encryptionSalt;
|
|
1402
|
+
}
|
|
1412
1403
|
}
|
|
1413
1404
|
else {
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
throw new Error(constants_1.KeyringControllerError.MissingCredentials);
|
|
1405
|
+
if (typeof password !== 'string') {
|
|
1406
|
+
throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
|
|
1407
|
+
}
|
|
1408
|
+
vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decrypt(password, encryptedVault);
|
|
1409
|
+
__classPrivateFieldSet(this, _KeyringController_password, password, "f");
|
|
1420
1410
|
}
|
|
1421
|
-
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1422
|
-
const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
|
|
1423
1411
|
if (!isSerializedKeyringsArray(vault)) {
|
|
1424
1412
|
throw new Error(constants_1.KeyringControllerError.VaultDataError);
|
|
1425
1413
|
}
|
|
@@ -1427,8 +1415,10 @@ async function _KeyringController_unlockKeyrings(credentials) {
|
|
|
1427
1415
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1428
1416
|
this.update((state) => {
|
|
1429
1417
|
state.keyrings = updatedKeyrings;
|
|
1430
|
-
|
|
1431
|
-
|
|
1418
|
+
if (updatedState.encryptionKey || updatedState.encryptionSalt) {
|
|
1419
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1420
|
+
state.encryptionSalt = updatedState.encryptionSalt;
|
|
1421
|
+
}
|
|
1432
1422
|
});
|
|
1433
1423
|
return { keyrings, newMetadata };
|
|
1434
1424
|
});
|
|
@@ -1436,38 +1426,57 @@ async function _KeyringController_unlockKeyrings(credentials) {
|
|
|
1436
1426
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
|
|
1437
1427
|
// Ensure no duplicate accounts are persisted.
|
|
1438
1428
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this);
|
|
1439
|
-
|
|
1429
|
+
const { encryptionKey, encryptionSalt, vault } = this.state;
|
|
1430
|
+
// READ THIS CAREFULLY:
|
|
1431
|
+
// We do check if the vault is still considered up-to-date, if not, we would not re-use the
|
|
1432
|
+
// cached key and we will re-generate a new one (based on the password).
|
|
1433
|
+
//
|
|
1434
|
+
// This helps doing seamless updates of the vault. Useful in case we change some cryptographic
|
|
1435
|
+
// parameters to the KDF.
|
|
1436
|
+
const useCachedKey = encryptionKey && vault && __classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated?.(vault);
|
|
1437
|
+
if (!__classPrivateFieldGet(this, _KeyringController_password, "f") && !encryptionKey) {
|
|
1440
1438
|
throw new Error(constants_1.KeyringControllerError.MissingCredentials);
|
|
1441
1439
|
}
|
|
1442
1440
|
const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1443
1441
|
if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
|
|
1444
1442
|
throw new Error(constants_1.KeyringControllerError.NoHdKeyring);
|
|
1445
1443
|
}
|
|
1446
|
-
const
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1444
|
+
const updatedState = {};
|
|
1445
|
+
if (__classPrivateFieldGet(this, _KeyringController_cacheEncryptionKey, "f")) {
|
|
1446
|
+
assertIsExportableKeyEncryptor(__classPrivateFieldGet(this, _KeyringController_encryptor, "f"));
|
|
1447
|
+
if (useCachedKey) {
|
|
1448
|
+
const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
|
|
1449
|
+
const vaultJSON = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
|
|
1450
|
+
vaultJSON.salt = encryptionSalt;
|
|
1451
|
+
updatedState.vault = JSON.stringify(vaultJSON);
|
|
1452
|
+
}
|
|
1453
|
+
else if (__classPrivateFieldGet(this, _KeyringController_password, "f")) {
|
|
1454
|
+
const { vault: newVault, exportedKeyString } = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithDetail(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
1455
|
+
updatedState.vault = newVault;
|
|
1456
|
+
updatedState.encryptionKey = exportedKeyString;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
else {
|
|
1460
|
+
assertIsValidPassword(__classPrivateFieldGet(this, _KeyringController_password, "f"));
|
|
1461
|
+
updatedState.vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encrypt(__classPrivateFieldGet(this, _KeyringController_password, "f"), serializedKeyrings);
|
|
1462
|
+
}
|
|
1463
|
+
if (!updatedState.vault) {
|
|
1464
|
+
throw new Error(constants_1.KeyringControllerError.MissingVaultData);
|
|
1453
1465
|
}
|
|
1454
|
-
const updatedState = {
|
|
1455
|
-
vault: JSON.stringify(encryptedVault),
|
|
1456
|
-
encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").exported,
|
|
1457
|
-
encryptionSalt: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt,
|
|
1458
|
-
};
|
|
1459
1466
|
const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
|
|
1460
1467
|
this.update((state) => {
|
|
1461
1468
|
state.vault = updatedState.vault;
|
|
1462
1469
|
state.keyrings = updatedKeyrings;
|
|
1463
|
-
|
|
1464
|
-
|
|
1470
|
+
if (updatedState.encryptionKey) {
|
|
1471
|
+
state.encryptionKey = updatedState.encryptionKey;
|
|
1472
|
+
state.encryptionSalt = JSON.parse(updatedState.vault).salt;
|
|
1473
|
+
}
|
|
1465
1474
|
});
|
|
1466
1475
|
return true;
|
|
1467
1476
|
});
|
|
1468
1477
|
}, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
|
|
1469
1478
|
const { vault } = this.state;
|
|
1470
|
-
if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1479
|
+
if (!vault || !__classPrivateFieldGet(this, _KeyringController_password, "f") || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
|
|
1471
1480
|
return false;
|
|
1472
1481
|
}
|
|
1473
1482
|
return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
|
|
@@ -1706,16 +1715,13 @@ async function _KeyringController_persistOrRollback(callback) {
|
|
|
1706
1715
|
async function _KeyringController_withRollback(callback) {
|
|
1707
1716
|
return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
|
|
1708
1717
|
const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
|
|
1709
|
-
const
|
|
1710
|
-
const currentEncryptionSalt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.salt;
|
|
1718
|
+
const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
|
|
1711
1719
|
try {
|
|
1712
1720
|
return await callback({ releaseLock });
|
|
1713
1721
|
}
|
|
1714
1722
|
catch (e) {
|
|
1715
|
-
// Keyrings and
|
|
1716
|
-
|
|
1717
|
-
__classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_useEncryptionKey).call(this, currentEncryptionKey, currentEncryptionSalt);
|
|
1718
|
-
}
|
|
1723
|
+
// Keyrings and password are restored to their previous state
|
|
1724
|
+
__classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
|
|
1719
1725
|
await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
|
|
1720
1726
|
throw e;
|
|
1721
1727
|
}
|