@metamask-previews/keyring-controller 22.0.2-preview-2873423 → 22.0.2-preview-cf465cec

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.
@@ -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_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;
39
+ var _KeyringController_instances, _KeyringController_controllerOperationMutex, _KeyringController_vaultOperationMutex, _KeyringController_keyringBuilders, _KeyringController_encryptor, _KeyringController_keyrings, _KeyringController_unsupportedKeyrings, _KeyringController_encryptionKey, _KeyringController_qrKeyringStateListener, _KeyringController_registerMessageHandlers, _KeyringController_getKeyringById, _KeyringController_getKeyringByIdOrDefault, _KeyringController_getKeyringMetadata, _KeyringController_getKeyringBuilderForType, _KeyringController_addQRKeyring, _KeyringController_subscribeToQRKeyringEvents, _KeyringController_unsubscribeFromQRKeyringsEvents, _KeyringController_createNewVaultWithKeyring, _KeyringController_deriveEncryptionKey, _KeyringController_useEncryptionKey, _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,23 +270,17 @@ 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);
274
273
  _KeyringController_keyrings.set(this, void 0);
275
274
  _KeyringController_unsupportedKeyrings.set(this, void 0);
276
- _KeyringController_password.set(this, void 0);
275
+ _KeyringController_encryptionKey.set(this, void 0);
277
276
  _KeyringController_qrKeyringStateListener.set(this, void 0);
278
277
  __classPrivateFieldSet(this, _KeyringController_keyringBuilders, keyringBuilders
279
278
  ? keyringBuilders.concat(defaultKeyringBuilders)
280
279
  : 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
- }
290
284
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_registerMessageHandlers).call(this);
291
285
  }
292
286
  /**
@@ -661,7 +655,7 @@ class KeyringController extends base_controller_1.BaseController {
661
655
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
662
656
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
663
657
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unsubscribeFromQRKeyringsEvents).call(this);
664
- __classPrivateFieldSet(this, _KeyringController_password, undefined, "f");
658
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, undefined, "f");
665
659
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
666
660
  this.update((state) => {
667
661
  state.isUnlocked = false;
@@ -845,16 +839,7 @@ class KeyringController extends base_controller_1.BaseController {
845
839
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertIsUnlocked).call(this);
846
840
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_persistOrRollback).call(this, async () => {
847
841
  assertIsValidPassword(password);
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
- }
842
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password);
858
843
  });
859
844
  }
860
845
  /**
@@ -862,12 +847,13 @@ class KeyringController extends base_controller_1.BaseController {
862
847
  * using the given encryption key and salt.
863
848
  *
864
849
  * @param encryptionKey - Key to unlock the keychain.
865
- * @param encryptionSalt - Salt to unlock the keychain.
866
850
  * @returns Promise resolving when the operation completes.
867
851
  */
868
- async submitEncryptionKey(encryptionKey, encryptionSalt) {
852
+ async submitEncryptionKey(encryptionKey) {
869
853
  const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
870
- const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, undefined, encryptionKey, encryptionSalt);
854
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, {
855
+ exportedEncryptionKey: encryptionKey,
856
+ });
871
857
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
872
858
  return result;
873
859
  });
@@ -895,7 +881,7 @@ class KeyringController extends base_controller_1.BaseController {
895
881
  */
896
882
  async submitPassword(password) {
897
883
  const { newMetadata } = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
898
- const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, password);
884
+ const result = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_unlockKeyrings).call(this, { password });
899
885
  __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_setUnlocked).call(this);
900
886
  return result;
901
887
  });
@@ -905,6 +891,12 @@ class KeyringController extends base_controller_1.BaseController {
905
891
  // can attempt to upgrade the vault.
906
892
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withRollback).call(this, async () => {
907
893
  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
+ ignoreVautKeyMetadata: true,
899
+ });
908
900
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_updateVault).call(this);
909
901
  }
910
902
  });
@@ -1159,7 +1151,7 @@ class KeyringController extends base_controller_1.BaseController {
1159
1151
  }
1160
1152
  }
1161
1153
  exports.KeyringController = KeyringController;
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() {
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(), _KeyringController_encryptionKey = new WeakMap(), _KeyringController_qrKeyringStateListener = new WeakMap(), _KeyringController_instances = new WeakSet(), _KeyringController_registerMessageHandlers = function _KeyringController_registerMessageHandlers() {
1163
1155
  this.messagingSystem.registerActionHandler(`${name}:signMessage`, this.signMessage.bind(this));
1164
1156
  this.messagingSystem.registerActionHandler(`${name}:signEip7702Authorization`, this.signEip7702Authorization.bind(this));
1165
1157
  this.messagingSystem.registerActionHandler(`${name}:signPersonalMessage`, this.signPersonalMessage.bind(this));
@@ -1239,10 +1231,64 @@ async function _KeyringController_createNewVaultWithKeyring(password, keyring) {
1239
1231
  delete state.encryptionKey;
1240
1232
  delete state.encryptionSalt;
1241
1233
  });
1242
- __classPrivateFieldSet(this, _KeyringController_password, password, "f");
1234
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, password);
1243
1235
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_clearKeyrings).call(this);
1244
1236
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_createKeyringWithFirstAccount).call(this, keyring.type, keyring.opts);
1245
1237
  __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
+ */
1250
+ async function _KeyringController_deriveEncryptionKey(password, options = {
1251
+ ignoreVautKeyMetadata: false,
1252
+ }) {
1253
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1254
+ const { vault } = this.state;
1255
+ if (typeof password !== 'string') {
1256
+ throw new TypeError(constants_1.KeyringControllerError.WrongPasswordType);
1257
+ }
1258
+ let salt, keyMetadata;
1259
+ if (vault && !options.ignoreVautKeyMetadata) {
1260
+ const parsedVault = JSON.parse(vault);
1261
+ salt = parsedVault.salt;
1262
+ keyMetadata = parsedVault.keyMetadata;
1263
+ }
1264
+ else {
1265
+ salt = __classPrivateFieldGet(this, _KeyringController_encryptor, "f").generateSalt();
1266
+ }
1267
+ const exportedEncryptionKey = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").exportKey(await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").keyFromPassword(password, salt, true, keyMetadata));
1268
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, {
1269
+ salt,
1270
+ exported: exportedEncryptionKey,
1271
+ }, "f");
1272
+ }, _KeyringController_useEncryptionKey =
1273
+ /**
1274
+ * Use the provided encryption key and salt to set the
1275
+ * encryptionKey class variable. This method is used
1276
+ * when the user provides an encryption key and salt
1277
+ * to unlock the keychain, instead of using a password.
1278
+ *
1279
+ * @param encryptionKey - The encryption key to use.
1280
+ * @param encryptionSalt - The salt to use for the encryption key.
1281
+ */
1282
+ async function _KeyringController_useEncryptionKey(encryptionKey, encryptionSalt) {
1283
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertControllerMutexIsLocked).call(this);
1284
+ if (typeof encryptionKey !== 'string' ||
1285
+ typeof encryptionSalt !== 'string') {
1286
+ throw new TypeError(constants_1.KeyringControllerError.WrongEncryptionKeyType);
1287
+ }
1288
+ __classPrivateFieldSet(this, _KeyringController_encryptionKey, {
1289
+ salt: encryptionSalt,
1290
+ exported: encryptionKey,
1291
+ }, "f");
1246
1292
  }, _KeyringController_verifySeedPhrase =
1247
1293
  /**
1248
1294
  * Internal non-exclusive method to verify the seed phrase.
@@ -1331,7 +1377,7 @@ async function _KeyringController_getSerializedKeyrings({ includeUnsupported } =
1331
1377
  async function _KeyringController_getSessionState() {
1332
1378
  return {
1333
1379
  keyrings: await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this),
1334
- password: __classPrivateFieldGet(this, _KeyringController_password, "f"),
1380
+ encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f"),
1335
1381
  };
1336
1382
  }, _KeyringController_restoreSerializedKeyrings =
1337
1383
  /**
@@ -1360,54 +1406,28 @@ async function _KeyringController_restoreSerializedKeyrings(serializedKeyrings)
1360
1406
  * Unlock Keyrings, decrypting the vault and deserializing all
1361
1407
  * keyrings contained in it, using a password or an encryption key with salt.
1362
1408
  *
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.
1409
+ * @param credentials - The credentials to unlock the keyrings.
1366
1410
  * @returns A promise resolving to the deserialized keyrings array.
1367
1411
  */
1368
- async function _KeyringController_unlockKeyrings(password, encryptionKey, encryptionSalt) {
1412
+ async function _KeyringController_unlockKeyrings(credentials) {
1369
1413
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1370
- const encryptedVault = this.state.vault;
1371
- if (!encryptedVault) {
1414
+ if (!this.state.vault) {
1372
1415
  throw new Error(constants_1.KeyringControllerError.VaultError);
1373
1416
  }
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
- }
1417
+ const parsedEncryptedVault = JSON.parse(this.state.vault);
1418
+ if ('password' in credentials) {
1419
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_deriveEncryptionKey).call(this, credentials.password);
1403
1420
  }
1404
1421
  else {
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");
1422
+ const { exportedEncryptionKey } = credentials;
1423
+ await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_useEncryptionKey).call(this, exportedEncryptionKey, parsedEncryptedVault.salt);
1424
+ }
1425
+ const encryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.exported;
1426
+ if (!encryptionKey) {
1427
+ throw new Error(constants_1.KeyringControllerError.MissingCredentials);
1410
1428
  }
1429
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(encryptionKey);
1430
+ const vault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").decryptWithKey(key, parsedEncryptedVault);
1411
1431
  if (!isSerializedKeyringsArray(vault)) {
1412
1432
  throw new Error(constants_1.KeyringControllerError.VaultDataError);
1413
1433
  }
@@ -1415,10 +1435,8 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1415
1435
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1416
1436
  this.update((state) => {
1417
1437
  state.keyrings = updatedKeyrings;
1418
- if (updatedState.encryptionKey || updatedState.encryptionSalt) {
1419
- state.encryptionKey = updatedState.encryptionKey;
1420
- state.encryptionSalt = updatedState.encryptionSalt;
1421
- }
1438
+ state.encryptionKey = encryptionKey;
1439
+ state.encryptionSalt = parsedEncryptedVault.salt;
1422
1440
  });
1423
1441
  return { keyrings, newMetadata };
1424
1442
  });
@@ -1426,57 +1444,38 @@ async function _KeyringController_unlockKeyrings(password, encryptionKey, encryp
1426
1444
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withVaultLock).call(this, async () => {
1427
1445
  // Ensure no duplicate accounts are persisted.
1428
1446
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_assertNoDuplicateAccounts).call(this);
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) {
1447
+ if (!__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")) {
1438
1448
  throw new Error(constants_1.KeyringControllerError.MissingCredentials);
1439
1449
  }
1440
1450
  const serializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1441
1451
  if (!serializedKeyrings.some((keyring) => keyring.type === KeyringTypes.hd)) {
1442
1452
  throw new Error(constants_1.KeyringControllerError.NoHdKeyring);
1443
1453
  }
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);
1454
+ const key = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").importKey(__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").exported);
1455
+ const encryptedVault = await __classPrivateFieldGet(this, _KeyringController_encryptor, "f").encryptWithKey(key, serializedKeyrings);
1456
+ if (__classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt) {
1457
+ // We need to include the salt used to derive
1458
+ // the encryption key, to be able to derive it
1459
+ // from password again.
1460
+ encryptedVault.salt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt;
1465
1461
  }
1462
+ const updatedState = {
1463
+ vault: JSON.stringify(encryptedVault),
1464
+ encryptionKey: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").exported,
1465
+ encryptionSalt: __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f").salt,
1466
+ };
1466
1467
  const updatedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getUpdatedKeyrings).call(this);
1467
1468
  this.update((state) => {
1468
1469
  state.vault = updatedState.vault;
1469
1470
  state.keyrings = updatedKeyrings;
1470
- if (updatedState.encryptionKey) {
1471
- state.encryptionKey = updatedState.encryptionKey;
1472
- state.encryptionSalt = JSON.parse(updatedState.vault).salt;
1473
- }
1471
+ state.encryptionKey = updatedState.encryptionKey;
1472
+ state.encryptionSalt = updatedState.encryptionSalt;
1474
1473
  });
1475
1474
  return true;
1476
1475
  });
1477
1476
  }, _KeyringController_isNewEncryptionAvailable = function _KeyringController_isNewEncryptionAvailable() {
1478
1477
  const { vault } = this.state;
1479
- if (!vault || !__classPrivateFieldGet(this, _KeyringController_password, "f") || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
1478
+ if (!vault || !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated) {
1480
1479
  return false;
1481
1480
  }
1482
1481
  return !__classPrivateFieldGet(this, _KeyringController_encryptor, "f").isVaultUpdated(vault);
@@ -1715,13 +1714,16 @@ async function _KeyringController_persistOrRollback(callback) {
1715
1714
  async function _KeyringController_withRollback(callback) {
1716
1715
  return __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_withControllerLock).call(this, async ({ releaseLock }) => {
1717
1716
  const currentSerializedKeyrings = await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_getSerializedKeyrings).call(this);
1718
- const currentPassword = __classPrivateFieldGet(this, _KeyringController_password, "f");
1717
+ const currentEncryptionKey = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.exported;
1718
+ const currentEncryptionSalt = __classPrivateFieldGet(this, _KeyringController_encryptionKey, "f")?.salt;
1719
1719
  try {
1720
1720
  return await callback({ releaseLock });
1721
1721
  }
1722
1722
  catch (e) {
1723
- // Keyrings and password are restored to their previous state
1724
- __classPrivateFieldSet(this, _KeyringController_password, currentPassword, "f");
1723
+ // Keyrings and encryption credentials are restored to their previous state
1724
+ if (currentEncryptionKey && currentEncryptionSalt) {
1725
+ __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_useEncryptionKey).call(this, currentEncryptionKey, currentEncryptionSalt);
1726
+ }
1725
1727
  await __classPrivateFieldGet(this, _KeyringController_instances, "m", _KeyringController_restoreSerializedKeyrings).call(this, currentSerializedKeyrings);
1726
1728
  throw e;
1727
1729
  }