forked from mystiq/hydrogen-web
migration to initialize & restore e2ee identity backup
This commit is contained in:
parent
3a064d6796
commit
a1c66738db
2 changed files with 30 additions and 0 deletions
|
@ -19,6 +19,8 @@ import {StorageError} from "../common";
|
||||||
import {LogItem} from "../../../logging/LogItem.js";
|
import {LogItem} from "../../../logging/LogItem.js";
|
||||||
import {IDBKey} from "./Transaction";
|
import {IDBKey} from "./Transaction";
|
||||||
|
|
||||||
|
// this is the part of the Transaction class API that is used here and in the Store subclass,
|
||||||
|
// to make it easier to replace it with alternative implementations in schema.ts and unit tests
|
||||||
export interface ITransaction {
|
export interface ITransaction {
|
||||||
idbFactory: IDBFactory;
|
idbFactory: IDBFactory;
|
||||||
IDBKeyRange: typeof IDBKeyRange;
|
IDBKeyRange: typeof IDBKeyRange;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import {IDOMStorage} from "./types";
|
import {IDOMStorage} from "./types";
|
||||||
|
import {ITransaction} from "./QueryTarget";
|
||||||
import {iterateCursor, NOT_DONE, reqAsPromise} from "./utils";
|
import {iterateCursor, NOT_DONE, reqAsPromise} from "./utils";
|
||||||
import {RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from "../../room/members/RoomMember.js";
|
import {RoomMember, EVENT_TYPE as MEMBER_EVENT_TYPE} from "../../room/members/RoomMember.js";
|
||||||
import {addRoomToIdentity} from "../../e2ee/DeviceTracker.js";
|
import {addRoomToIdentity} from "../../e2ee/DeviceTracker.js";
|
||||||
|
@ -7,6 +8,7 @@ import {SummaryData} from "../../room/RoomSummary";
|
||||||
import {RoomMemberStore, MemberData} from "./stores/RoomMemberStore";
|
import {RoomMemberStore, MemberData} from "./stores/RoomMemberStore";
|
||||||
import {RoomStateEntry} from "./stores/RoomStateStore";
|
import {RoomStateEntry} from "./stores/RoomStateStore";
|
||||||
import {SessionStore} from "./stores/SessionStore";
|
import {SessionStore} from "./stores/SessionStore";
|
||||||
|
import {Store} from "./Store";
|
||||||
import {encodeScopeTypeKey} from "./stores/OperationStore";
|
import {encodeScopeTypeKey} from "./stores/OperationStore";
|
||||||
import {MAX_UNICODE} from "./stores/common";
|
import {MAX_UNICODE} from "./stores/common";
|
||||||
import {LogItem} from "../../../logging/LogItem.js";
|
import {LogItem} from "../../../logging/LogItem.js";
|
||||||
|
@ -28,6 +30,7 @@ export const schema: MigrationFunc[] = [
|
||||||
createTimelineRelationsStore,
|
createTimelineRelationsStore,
|
||||||
fixMissingRoomsInUserIdentities,
|
fixMissingRoomsInUserIdentities,
|
||||||
changeSSSSKeyPrefix,
|
changeSSSSKeyPrefix,
|
||||||
|
backupAndRestoreE2EEAccountToLocalStorage
|
||||||
];
|
];
|
||||||
// TODO: how to deal with git merge conflicts of this array?
|
// TODO: how to deal with git merge conflicts of this array?
|
||||||
|
|
||||||
|
@ -215,3 +218,28 @@ async function changeSSSSKeyPrefix(db: IDBDatabase, txn: IDBTransaction) {
|
||||||
session.put({key: `${SESSION_E2EE_KEY_PREFIX}ssssKey`, value: ssssKey});
|
session.put({key: `${SESSION_E2EE_KEY_PREFIX}ssssKey`, value: ssssKey});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// v13
|
||||||
|
async function backupAndRestoreE2EEAccountToLocalStorage(db: IDBDatabase, txn: IDBTransaction, localStorage: IDOMStorage, log: LogItem) {
|
||||||
|
const session = txn.objectStore("session");
|
||||||
|
// the Store object gets passed in several things through the Transaction class (a wrapper around IDBTransaction),
|
||||||
|
// the only thing we should need here is the databaseName though, so we mock it out.
|
||||||
|
// ideally we should have an easier way to go from the idb primitive layer to the specific store classes where
|
||||||
|
// we implement logic, but for now we need this.
|
||||||
|
const databaseNameHelper: ITransaction = {
|
||||||
|
databaseName: db.name,
|
||||||
|
get idbFactory(): IDBFactory { throw new Error("unused");},
|
||||||
|
get IDBKeyRange(): typeof IDBKeyRange { throw new Error("unused");},
|
||||||
|
addWriteError() {},
|
||||||
|
};
|
||||||
|
const sessionStore = new SessionStore(new Store(session, databaseNameHelper), localStorage);
|
||||||
|
// if we already have an e2ee identity, write a backup to local storage.
|
||||||
|
// further updates to e2ee keys in the session store will also write to local storage from 0.2.15 on,
|
||||||
|
// but here we make sure a backup is immediately created after installing the update and we don't wait until
|
||||||
|
// the olm account needs to change
|
||||||
|
sessionStore.writeE2EEIdentityToLocalStorage();
|
||||||
|
// and if we already have a backup, restore it now for any missing key in idb.
|
||||||
|
// this will restore the backup every time the idb database is dropped as it will
|
||||||
|
// run through all the migration steps when recreating it.
|
||||||
|
const restored = await sessionStore.tryRestoreE2EEIdentityFromLocalStorage(log);
|
||||||
|
log.set("restored", restored);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue