mark all inbound sessions to be backed up again when changing version
This commit is contained in:
parent
d9e6164a5c
commit
ae5cc17290
4 changed files with 37 additions and 6 deletions
|
@ -203,21 +203,32 @@ export class Session {
|
|||
this._storage.storeNames.accountData,
|
||||
]);
|
||||
if (await this._createKeyBackup(key, readTxn, log)) {
|
||||
await this._writeSSSSKey(key);
|
||||
// only after having read a secret, write the key
|
||||
// as we only find out if it was good if the MAC verification succeeds
|
||||
await this._writeSSSSKey(key, log);
|
||||
this._keyBackup.get().flush(log);
|
||||
return key;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async _writeSSSSKey(key) {
|
||||
// only after having read a secret, write the key
|
||||
// as we only find out if it was good if the MAC verification succeeds
|
||||
async _writeSSSSKey(key, log) {
|
||||
// we're going to write the 4S key, and also the backup version.
|
||||
// this way, we can detect when we enter a key for a new backup version
|
||||
// and mark all inbound sessions to be backed up again
|
||||
const backupVersion = this._keyBackup.get()?.version;
|
||||
const writeTxn = await this._storage.readWriteTxn([
|
||||
this._storage.storeNames.session,
|
||||
this._storage.storeNames.inboundGroupSessions,
|
||||
]);
|
||||
try {
|
||||
ssssWriteKey(key, writeTxn);
|
||||
const previousBackupVersion = await ssssWriteKey(key, backupVersion, writeTxn);
|
||||
log.set("previousBackupVersion", previousBackupVersion);
|
||||
log.set("backupVersion", backupVersion);
|
||||
if (typeof previousBackupVersion === "number" && previousBackupVersion !== backupVersion) {
|
||||
const amountMarked = await this._keyBackup.markAllForBackup(writeTxn);
|
||||
log.set("amountMarkedForBackup", amountMarked);
|
||||
}
|
||||
} catch (err) {
|
||||
writeTxn.abort();
|
||||
throw err;
|
||||
|
|
|
@ -62,6 +62,10 @@ export class KeyBackup {
|
|||
}
|
||||
}
|
||||
|
||||
markAllForBackup(txn: Transaction): Promise<number> {
|
||||
return txn.inboundGroupSessions.markAllAsNotBackedUp();
|
||||
}
|
||||
|
||||
flush(log: ILogItem): void {
|
||||
if (!this.operationInProgress.get()) {
|
||||
log.wrapDetached("flush key backup", async log => {
|
||||
|
|
|
@ -27,6 +27,7 @@ import type * as OlmNamespace from "@matrix-org/olm"
|
|||
type Olm = typeof OlmNamespace;
|
||||
|
||||
const SSSS_KEY = `${SESSION_E2EE_KEY_PREFIX}ssssKey`;
|
||||
const BACKUPVERSION_KEY = `${SESSION_E2EE_KEY_PREFIX}keyBackupVersion`;
|
||||
|
||||
export enum KeyType {
|
||||
"RecoveryKey",
|
||||
|
@ -49,8 +50,11 @@ async function readDefaultKeyDescription(storage: Storage): Promise<KeyDescripti
|
|||
return new KeyDescription(id, keyAccountData.content as KeyDescriptionData);
|
||||
}
|
||||
|
||||
export async function writeKey(key: Key, txn: Transaction): Promise<void> {
|
||||
export async function writeKey(key: Key, keyBackupVersion: number, txn: Transaction): Promise<number | undefined> {
|
||||
const existingVersion: number | undefined = await txn.session.get(BACKUPVERSION_KEY);
|
||||
txn.session.set(BACKUPVERSION_KEY, keyBackupVersion);
|
||||
txn.session.set(SSSS_KEY, {id: key.id, binaryKey: key.binaryKey});
|
||||
return existingVersion;
|
||||
}
|
||||
|
||||
export async function readKey(txn: Transaction): Promise<Key | undefined> {
|
||||
|
|
|
@ -91,4 +91,16 @@ export class InboundGroupSessionStore {
|
|||
this._store.put(entry);
|
||||
}
|
||||
}
|
||||
|
||||
async markAllAsNotBackedUp(): Promise<number> {
|
||||
const backedUpKey = this._store.IDBKeyRange.only(BackupStatus.BackedUp);
|
||||
let count = 0;
|
||||
await this._store.index("byBackup").iterateValues(backedUpKey, (val: InboundGroupSessionEntry, key: IDBValidKey, cur: IDBCursorWithValue) => {
|
||||
val.backup = BackupStatus.NotBackedUp;
|
||||
cur.update(val);
|
||||
count += 1;
|
||||
return false;
|
||||
});
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue