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.
This commit is contained in:
J. Ryan Stinnett 2020-08-28 12:10:17 +01:00
parent 3a98b4b4e9
commit f634c3a71e
2 changed files with 20 additions and 15 deletions

View file

@ -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,
};

View file

@ -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,