From f634c3a71e5ae049c890a814eb9459b5db263b17 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 28 Aug 2020 12:10:17 +0100 Subject: [PATCH] Add secret storage cache callback to avoid prompts This supplies a cache callback to the JS SDK so that we can be notified if a new storage key is created e.g. by resetting secret storage. This allows it to be supplied automatically in case it's needed in the same user operation, as it is when resetting both secret storage and cross-signing together. --- src/CrossSigningManager.js | 27 +++++++++++-------- .../CreateSecretStorageDialog.js | 8 +++--- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index b15290b9c3..0353bfc5ae 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -69,19 +69,19 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) { if (keyInfoEntries.length > 1) { throw new Error("Multiple storage key requests not implemented"); } - const [name, info] = keyInfoEntries[0]; + const [keyId, keyInfo] = keyInfoEntries[0]; // Check the in-memory cache - if (isCachingAllowed() && secretStorageKeys[name]) { - return [name, secretStorageKeys[name]]; + if (isCachingAllowed() && secretStorageKeys[keyId]) { + return [keyId, secretStorageKeys[keyId]]; } const inputToKey = async ({ passphrase, recoveryKey }) => { if (passphrase) { return deriveKey( passphrase, - info.passphrase.salt, - info.passphrase.iterations, + keyInfo.passphrase.salt, + keyInfo.passphrase.iterations, ); } else { return decodeRecoveryKey(recoveryKey); @@ -93,10 +93,10 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) { AccessSecretStorageDialog, /* props= */ { - keyInfo: info, + keyInfo, checkPrivateKey: async (input) => { const key = await inputToKey(input); - return await MatrixClientPeg.get().checkSecretStorageKey(key, info); + return await MatrixClientPeg.get().checkSecretStorageKey(key, keyInfo); }, }, /* className= */ null, @@ -118,11 +118,15 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) { const key = await inputToKey(input); // Save to cache to avoid future prompts in the current session - if (isCachingAllowed()) { - secretStorageKeys[name] = key; - } + cacheSecretStorageKey(keyId, key); - return [name, key]; + return [keyId, key]; +} + +function cacheSecretStorageKey(keyId, key) { + if (isCachingAllowed()) { + secretStorageKeys[keyId] = key; + } } const onSecretRequested = async function({ @@ -170,6 +174,7 @@ const onSecretRequested = async function({ export const crossSigningCallbacks = { getSecretStorageKey, + cacheSecretStorageKey, onSecretRequested, }; diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js index 00216e3765..0a1a0b02b3 100644 --- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js @@ -282,15 +282,15 @@ export default class CreateSecretStorageDialog extends React.PureComponent { try { if (forceReset) { console.log("Forcing cross-signing and secret storage reset"); - await cli.bootstrapCrossSigning({ - authUploadDeviceSigningKeys: this._doBootstrapUIAuth, - setupNewCrossSigning: true, - }); await cli.bootstrapSecretStorage({ createSecretStorageKey: async () => this._recoveryKey, setupNewKeyBackup: true, setupNewSecretStorage: true, }); + await cli.bootstrapCrossSigning({ + authUploadDeviceSigningKeys: this._doBootstrapUIAuth, + setupNewCrossSigning: true, + }); } else { await cli.bootstrapCrossSigning({ authUploadDeviceSigningKeys: this._doBootstrapUIAuth,