Skip to content

Commit

Permalink
poll secret inbox
Browse files Browse the repository at this point in the history
  • Loading branch information
BillCarsonFr committed Oct 13, 2023
1 parent fda8309 commit 6887070
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 15 deletions.
11 changes: 5 additions & 6 deletions src/rust-crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,13 @@ export async function initRustCrypto(

// Check if there are any key backup secrets pending processing. There may be multiple secrets to process if several devices have gossiped them.
// The `registerReceiveSecretCallback` function will only be triggered for new secrets. If the client is restarted before processing them, the secrets will need to be manually handled.
const pendingValues: string[] = await olmMachine.getSecretsFromInbox("m.megolm_backup.v1");
pendingValues.forEach((value) => {
rustCrypto.onReceiveSecret("m.megolm_backup.v1", value);
});
rustCrypto.checkSecrets("m.megolm_backup.v1");

// Register a callback to be notified when a new secret is received, as for now only the key backup secret is supported (the cross signing secrets are handled automatically by the OlmMachine)
await olmMachine.registerReceiveSecretCallback((name: string, value: string) =>
rustCrypto.onReceiveSecret(name, value),
await olmMachine.registerReceiveSecretCallback((name: string, _value: string) =>
// Instead of directly checking the secret value, we poll the inbox to get all values for that secret type.
// Once we have all the values, we can safely clear the secret inbox.
rustCrypto.checkSecrets(name),
);

// Tell the OlmMachine to think about its outgoing requests before we hand control back to the application.
Expand Down
35 changes: 26 additions & 9 deletions src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1370,22 +1370,39 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
* @param name - the secret name
* @param base64 - the secret value base 64 encoded
*/
public async onReceiveSecret(name: string, value: string): Promise<void> {
private async handleSecretReceived(name: string, value: string): Promise<boolean> {
this.logger.debug(`onReceiveSecret: Received secret ${name}`);
if (name === "m.megolm_backup.v1") {
const isHandled = await this.backupManager.handleBackupSecretReceived(value);

if (isHandled) {
// The secret is valid and stored, clear the inbox.
// Important to call this after storing the secret as good hygiene.
await this.olmMachine.deleteSecretsFromInbox("m.megolm_backup.v1");
// XXXX at this point we should probably try to download the backup and import the keys,
// or at least retry for the current decryption failures?
// Maybe add some signaling when a new secret is received, and let clients handle it?
// as it's where the restore from backup APIs are exposed.

// XXXX at this point we should probably try to download the backup and import the keys,
// or at least retry for the current decryption failures?
// Maybe add some signaling when a new secret is received, and let clients handle it?
// as it's where the restore from backup APIs are
return isHandled;
}
return false;
}

/**
* Called when a new secret is received in the rust secret inbox.
*
* Will poll the secret inbox and handle the secrets received.
*
* @param name - The name of the secret received.
* @returns `true` if the secret has been handled and saved, `false` otherwise.
*/
public async checkSecrets(name: string): Promise<void> {
const pendingValues: string[] = await this.olmMachine.getSecretsFromInbox("m.megolm_backup.v1");
for (const value of pendingValues) {
if (await this.handleSecretReceived(name, value)) {
break;
}
}

// Important to call this after handling the secrets as good hygiene.
await this.olmMachine.deleteSecretsFromInbox(name);
}

/**
Expand Down

0 comments on commit 6887070

Please sign in to comment.