@@ -78,6 +78,18 @@ async function initializeKeyringController({
7878 return keyringController ;
7979}
8080
81+ /**
82+ * Delete the encryption key and salt from the `memStore` of the given keyring controller.
83+ *
84+ * @param keyringController - The keyring controller to delete the encryption key and salt from.
85+ */
86+ function deleteEncryptionKeyAndSalt ( keyringController : KeyringController ) {
87+ const keyringControllerState = keyringController . memStore . getState ( ) ;
88+ delete keyringControllerState . encryptionKey ;
89+ delete keyringControllerState . encryptionSalt ;
90+ keyringController . memStore . updateState ( keyringControllerState ) ;
91+ }
92+
8193describe ( 'KeyringController' , ( ) => {
8294 afterEach ( ( ) => {
8395 sinon . restore ( ) ;
@@ -199,83 +211,86 @@ describe('KeyringController', () => {
199211 } ) ;
200212
201213 describe ( 'when `cacheEncryptionKey` is enabled' , ( ) => {
202- it ( 'should save an up to date encryption salt to the `memStore` when `password` is unset and `encryptionKey` is set' , async ( ) => {
203- const keyringController = await initializeKeyringController ( {
204- password : PASSWORD ,
205- constructorOptions : {
206- cacheEncryptionKey : true ,
207- } ,
214+ describe ( 'when `encryptionKey` is set' , ( ) => {
215+ it ( 'should save an up to date encryption salt to the `memStore`' , async ( ) => {
216+ const keyringController = await initializeKeyringController ( {
217+ password : PASSWORD ,
218+ constructorOptions : {
219+ cacheEncryptionKey : true ,
220+ } ,
221+ } ) ;
222+ const vaultEncryptionKey = '🔑' ;
223+ const vaultEncryptionSalt = '🧂' ;
224+ const vault = JSON . stringify ( { salt : vaultEncryptionSalt } ) ;
225+ keyringController . store . updateState ( { vault } ) ;
226+
227+ await keyringController . unlockKeyrings (
228+ undefined ,
229+ vaultEncryptionKey ,
230+ vaultEncryptionSalt ,
231+ ) ;
232+
233+ expect ( keyringController . memStore . getState ( ) . encryptionKey ) . toBe (
234+ vaultEncryptionKey ,
235+ ) ;
236+ expect ( keyringController . memStore . getState ( ) . encryptionSalt ) . toBe (
237+ vaultEncryptionSalt ,
238+ ) ;
239+
240+ const response = await keyringController . persistAllKeyrings ( ) ;
241+
242+ expect ( response ) . toBe ( true ) ;
243+ expect ( keyringController . memStore . getState ( ) . encryptionKey ) . toBe (
244+ vaultEncryptionKey ,
245+ ) ;
246+ expect ( keyringController . memStore . getState ( ) . encryptionSalt ) . toBe (
247+ vaultEncryptionSalt ,
248+ ) ;
208249 } ) ;
209- delete keyringController . password ;
210- const vaultEncryptionKey = '🔑' ;
211- const vaultEncryptionSalt = '🧂' ;
212- const vault = JSON . stringify ( { salt : vaultEncryptionSalt } ) ;
213- keyringController . store . updateState ( { vault } ) ;
214-
215- await keyringController . unlockKeyrings (
216- undefined ,
217- vaultEncryptionKey ,
218- vaultEncryptionSalt ,
219- ) ;
220-
221- expect ( keyringController . memStore . getState ( ) . encryptionKey ) . toBe (
222- vaultEncryptionKey ,
223- ) ;
224- expect ( keyringController . memStore . getState ( ) . encryptionSalt ) . toBe (
225- vaultEncryptionSalt ,
226- ) ;
227-
228- const response = await keyringController . persistAllKeyrings ( ) ;
229-
230- expect ( response ) . toBe ( true ) ;
231- expect ( keyringController . memStore . getState ( ) . encryptionKey ) . toBe (
232- vaultEncryptionKey ,
233- ) ;
234- expect ( keyringController . memStore . getState ( ) . encryptionSalt ) . toBe (
235- vaultEncryptionSalt ,
236- ) ;
237250 } ) ;
238251
239- it ( 'should save an up to date encryption salt to the `memStore` when `password` is set through `createNewVaultAndKeychain`' , async ( ) => {
240- const keyringController = await initializeKeyringController ( {
241- password : PASSWORD ,
242- constructorOptions : {
243- cacheEncryptionKey : true ,
244- } ,
252+ describe ( 'when `encryptionKey` is not set and `password` is set' , ( ) => {
253+ it ( 'should save an up to date encryption salt to the `memStore` when `password` is set through `createNewVaultAndKeychain`' , async ( ) => {
254+ const keyringController = await initializeKeyringController ( {
255+ password : PASSWORD ,
256+ constructorOptions : {
257+ cacheEncryptionKey : true ,
258+ } ,
259+ } ) ;
260+ await keyringController . createNewVaultAndKeychain ( PASSWORD ) ;
261+ deleteEncryptionKeyAndSalt ( keyringController ) ;
262+
263+ const response = await keyringController . persistAllKeyrings ( ) ;
264+
265+ expect ( response ) . toBe ( true ) ;
266+ expect ( keyringController . memStore . getState ( ) . encryptionKey ) . toBe (
267+ MOCK_HARDCODED_KEY ,
268+ ) ;
269+ expect ( keyringController . memStore . getState ( ) . encryptionSalt ) . toBe (
270+ MOCK_ENCRYPTION_SALT ,
271+ ) ;
245272 } ) ;
246273
247- await keyringController . createNewVaultAndKeychain ( PASSWORD ) ;
248-
249- const response = await keyringController . persistAllKeyrings ( ) ;
250-
251- expect ( response ) . toBe ( true ) ;
252- expect ( keyringController . memStore . getState ( ) . encryptionKey ) . toBe (
253- MOCK_HARDCODED_KEY ,
254- ) ;
255- expect ( keyringController . memStore . getState ( ) . encryptionSalt ) . toBe (
256- MOCK_ENCRYPTION_SALT ,
257- ) ;
258- } ) ;
259-
260- it ( 'should save an up to date encryption salt to the ` memStore` when `password` is set through `submitPassword`' , async ( ) => {
261- const keyringController = await initializeKeyringController ( {
262- password : PASSWORD ,
263- constructorOptions : {
264- cacheEncryptionKey : true ,
265- } ,
274+ it ( 'should save an up to date encryption salt to the `memStore` when `password` is set through `submitPassword`' , async ( ) => {
275+ const keyringController = await initializeKeyringController ( {
276+ password : PASSWORD ,
277+ constructorOptions : {
278+ cacheEncryptionKey : true ,
279+ } ,
280+ } ) ;
281+ await keyringController . submitPassword ( PASSWORD ) ;
282+ deleteEncryptionKeyAndSalt ( keyringController ) ;
283+
284+ const response = await keyringController . persistAllKeyrings ( ) ;
285+
286+ expect ( response ) . toBe ( true ) ;
287+ expect ( keyringController . memStore . getState ( ) . encryptionKey ) . toBe (
288+ MOCK_HARDCODED_KEY ,
289+ ) ;
290+ expect ( keyringController . memStore . getState ( ) . encryptionSalt ) . toBe (
291+ MOCK_ENCRYPTION_SALT ,
292+ ) ;
266293 } ) ;
267-
268- await keyringController . submitPassword ( PASSWORD ) ;
269-
270- const response = await keyringController . persistAllKeyrings ( ) ;
271-
272- expect ( response ) . toBe ( true ) ;
273- expect ( keyringController . memStore . getState ( ) . encryptionKey ) . toBe (
274- MOCK_HARDCODED_KEY ,
275- ) ;
276- expect ( keyringController . memStore . getState ( ) . encryptionSalt ) . toBe (
277- MOCK_ENCRYPTION_SALT ,
278- ) ;
279294 } ) ;
280295 } ) ;
281296 } ) ;
@@ -836,29 +851,81 @@ describe('KeyringController', () => {
836851 } ) ;
837852
838853 describe ( 'with old vault format' , ( ) => {
839- [ true , false ] . forEach ( ( cacheEncryptionKey ) => {
840- describe ( `with cacheEncryptionKey = ${ cacheEncryptionKey } ` , ( ) => {
841- it ( 'should update the vault' , async ( ) => {
842- const mockEncryptor = new MockEncryptor ( ) ;
843- const keyringController = await initializeKeyringController ( {
844- password : PASSWORD ,
845- constructorOptions : {
846- cacheEncryptionKey : true ,
847- encryptor : mockEncryptor ,
848- } ,
849- } ) ;
850- const initialVault = keyringController . store . getState ( ) . vault ;
851- const updatedVaultMock =
852- '{"vault": "updated_vault_detail", "salt": "salt"}' ;
853- sinon . stub ( mockEncryptor , 'updateVault' ) . resolves ( updatedVaultMock ) ;
854- sinon . stub ( mockEncryptor , 'encrypt' ) . resolves ( updatedVaultMock ) ;
855-
856- await keyringController . unlockKeyrings ( PASSWORD ) ;
857- const updatedVault = keyringController . store . getState ( ) . vault ;
858-
859- expect ( initialVault ) . not . toBe ( updatedVault ) ;
860- expect ( updatedVault ) . toBe ( updatedVaultMock ) ;
854+ describe ( `with cacheEncryptionKey = true and encryptionKey is unset` , ( ) => {
855+ it ( 'should update the vault' , async ( ) => {
856+ const mockEncryptor = new MockEncryptor ( ) ;
857+ const keyringController = await initializeKeyringController ( {
858+ password : PASSWORD ,
859+ constructorOptions : {
860+ cacheEncryptionKey : true ,
861+ encryptor : mockEncryptor ,
862+ } ,
861863 } ) ;
864+ deleteEncryptionKeyAndSalt ( keyringController ) ;
865+ const initialVault = keyringController . store . getState ( ) . vault ;
866+ const mockEncryptionResult = {
867+ data : '0x1234' ,
868+ iv : 'an iv' ,
869+ } ;
870+ sinon . stub ( mockEncryptor , 'isVaultUpdated' ) . returns ( false ) ;
871+ sinon
872+ . stub ( mockEncryptor , 'encryptWithKey' )
873+ . resolves ( mockEncryptionResult ) ;
874+
875+ await keyringController . unlockKeyrings ( PASSWORD ) ;
876+ const updatedVault = keyringController . store . getState ( ) . vault ;
877+
878+ expect ( initialVault ) . not . toBe ( updatedVault ) ;
879+ expect ( updatedVault ) . toBe (
880+ JSON . stringify ( {
881+ ...mockEncryptionResult ,
882+ salt : MOCK_ENCRYPTION_SALT ,
883+ } ) ,
884+ ) ;
885+ } ) ;
886+ } ) ;
887+
888+ describe ( `with cacheEncryptionKey = true and encryptionKey is set` , ( ) => {
889+ it ( 'should not update the vault' , async ( ) => {
890+ const mockEncryptor = new MockEncryptor ( ) ;
891+ const keyringController = await initializeKeyringController ( {
892+ password : PASSWORD ,
893+ constructorOptions : {
894+ cacheEncryptionKey : true ,
895+ encryptor : mockEncryptor ,
896+ } ,
897+ } ) ;
898+ const initialVault = keyringController . store . getState ( ) . vault ;
899+ sinon . stub ( mockEncryptor , 'isVaultUpdated' ) . returns ( false ) ;
900+
901+ await keyringController . unlockKeyrings ( PASSWORD ) ;
902+ const updatedVault = keyringController . store . getState ( ) . vault ;
903+
904+ expect ( initialVault ) . toBe ( updatedVault ) ;
905+ } ) ;
906+ } ) ;
907+
908+ describe ( `with cacheEncryptionKey = false` , ( ) => {
909+ it ( 'should update the vault' , async ( ) => {
910+ const mockEncryptor = new MockEncryptor ( ) ;
911+ const keyringController = await initializeKeyringController ( {
912+ password : PASSWORD ,
913+ constructorOptions : {
914+ cacheEncryptionKey : false ,
915+ encryptor : mockEncryptor ,
916+ } ,
917+ } ) ;
918+ const initialVault = keyringController . store . getState ( ) . vault ;
919+ const updatedVaultMock =
920+ '{"vault": "updated_vault_detail", "salt": "salt"}' ;
921+ sinon . stub ( mockEncryptor , 'isVaultUpdated' ) . returns ( false ) ;
922+ sinon . stub ( mockEncryptor , 'encrypt' ) . resolves ( updatedVaultMock ) ;
923+
924+ await keyringController . unlockKeyrings ( PASSWORD ) ;
925+ const updatedVault = keyringController . store . getState ( ) . vault ;
926+
927+ expect ( initialVault ) . not . toBe ( updatedVault ) ;
928+ expect ( updatedVault ) . toBe ( updatedVaultMock ) ;
862929 } ) ;
863930 } ) ;
864931 } ) ;
0 commit comments