@@ -527,20 +527,6 @@ function assertIsExportableKeyEncryptor(
527527 }
528528}
529529
530- /**
531- * Assert that the encryption key is set.
532- *
533- * @param encryptionKey - The encryption key to check.
534- * @throws If the encryption key is not set.
535- */
536- function assertIsEncryptionKeySet (
537- encryptionKey : string | undefined ,
538- ) : asserts encryptionKey is string {
539- if ( ! encryptionKey ) {
540- throw new Error ( KeyringControllerError . EncryptionKeyNotSet ) ;
541- }
542- }
543-
544530/**
545531 * Assert that the provided password is a valid non-empty string.
546532 *
@@ -1491,7 +1477,30 @@ export class KeyringController extends BaseController<
14911477 * @returns The vault encryption key.
14921478 */
14931479 async exportEncryptionKey ( ) : Promise < string > {
1494- assertIsEncryptionKeySet ( this . state . encryptionKey ) ;
1480+ this . #assertIsUnlocked( ) ;
1481+ // There is a case where the controller is unlocked but the encryption key
1482+ // is not set, even when #cacheEncryptionKey is true. This happens when
1483+ // calling changePassword with the existing password. In this case, the
1484+ // encryption key is deleted, but the state is not recreated, because the
1485+ // session state does not change in this case, and #updateVault is not
1486+ // called in #persistOrRollback.
1487+ if ( ! this . state . encryptionKey ) {
1488+ assertIsExportableKeyEncryptor ( this . #encryptor) ;
1489+ assertIsValidPassword ( this . #password) ;
1490+ const result = await this . #encryptor. decryptWithDetail (
1491+ this . #password,
1492+ // Ignoring undefined. Assuming vault is set when unlocked.
1493+ this . state . vault as string ,
1494+ ) ;
1495+ if ( this . #cacheEncryptionKey) {
1496+ this . update ( ( state ) => {
1497+ state . encryptionKey = result . exportedKeyString ;
1498+ state . encryptionSalt = result . salt ;
1499+ } ) ;
1500+ }
1501+ return result . exportedKeyString ;
1502+ }
1503+
14951504 return this . state . encryptionKey ;
14961505 }
14971506
0 commit comments