forked from mystiq/hydrogen-web
rename session backup to key backup to be consistent with RoomKey
This commit is contained in:
parent
933a1b4636
commit
86caa5f9b1
13 changed files with 82 additions and 82 deletions
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||
|
||||
import {ViewModel} from "./ViewModel.js";
|
||||
import {KeyType} from "../matrix/ssss/index";
|
||||
import {Status} from "./session/settings/SessionBackupViewModel.js";
|
||||
import {Status} from "./session/settings/KeyBackupViewModel.js";
|
||||
|
||||
export class AccountSetupViewModel extends ViewModel {
|
||||
constructor(accountSetup) {
|
||||
|
@ -50,7 +50,7 @@ export class AccountSetupViewModel extends ViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
// this vm adopts the same shape as SessionBackupViewModel so the same view can be reused.
|
||||
// this vm adopts the same shape as KeyBackupViewModel so the same view can be reused.
|
||||
class DecryptDehydratedDeviceViewModel extends ViewModel {
|
||||
constructor(accountSetupViewModel, decryptedCallback) {
|
||||
super();
|
||||
|
|
|
@ -36,7 +36,7 @@ export class SessionStatusViewModel extends ViewModel {
|
|||
this._reconnector = reconnector;
|
||||
this._status = this._calculateState(reconnector.connectionStatus.get(), sync.status.get());
|
||||
this._session = session;
|
||||
this._setupSessionBackupUrl = this.urlCreator.urlForSegment("settings");
|
||||
this._setupKeyBackupUrl = this.urlCreator.urlForSegment("settings");
|
||||
this._dismissSecretStorage = false;
|
||||
}
|
||||
|
||||
|
@ -44,17 +44,17 @@ export class SessionStatusViewModel extends ViewModel {
|
|||
const update = () => this._updateStatus();
|
||||
this.track(this._sync.status.subscribe(update));
|
||||
this.track(this._reconnector.connectionStatus.subscribe(update));
|
||||
this.track(this._session.needsSessionBackup.subscribe(() => {
|
||||
this.track(this._session.needsKeyBackup.subscribe(() => {
|
||||
this.emitChange();
|
||||
}));
|
||||
}
|
||||
|
||||
get setupSessionBackupUrl () {
|
||||
return this._setupSessionBackupUrl;
|
||||
get setupKeyBackupUrl () {
|
||||
return this._setupKeyBackupUrl;
|
||||
}
|
||||
|
||||
get isShown() {
|
||||
return (this._session.needsSessionBackup.get() && !this._dismissSecretStorage) || this._status !== SessionStatus.Syncing;
|
||||
return (this._session.needsKeyBackup.get() && !this._dismissSecretStorage) || this._status !== SessionStatus.Syncing;
|
||||
}
|
||||
|
||||
get statusLabel() {
|
||||
|
@ -70,7 +70,7 @@ export class SessionStatusViewModel extends ViewModel {
|
|||
case SessionStatus.SyncError:
|
||||
return this.i18n`Sync failed because of ${this._sync.error}`;
|
||||
}
|
||||
if (this._session.needsSessionBackup.get()) {
|
||||
if (this._session.needsKeyBackup.get()) {
|
||||
return this.i18n`Set up session backup to decrypt older messages.`;
|
||||
}
|
||||
return "";
|
||||
|
@ -135,7 +135,7 @@ export class SessionStatusViewModel extends ViewModel {
|
|||
|
||||
get isSecretStorageShown() {
|
||||
// TODO: we need a model here where we can have multiple messages queued up and their buttons don't bleed into each other.
|
||||
return this._status === SessionStatus.Syncing && this._session.needsSessionBackup.get() && !this._dismissSecretStorage;
|
||||
return this._status === SessionStatus.Syncing && this._session.needsKeyBackup.get() && !this._dismissSecretStorage;
|
||||
}
|
||||
|
||||
get canDismiss() {
|
||||
|
|
|
@ -20,7 +20,7 @@ import {createEnum} from "../../../utils/enum";
|
|||
|
||||
export const Status = createEnum("Enabled", "SetupKey", "SetupPhrase", "Pending");
|
||||
|
||||
export class SessionBackupViewModel extends ViewModel {
|
||||
export class KeyBackupViewModel extends ViewModel {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
this._session = options.session;
|
||||
|
@ -43,7 +43,7 @@ export class SessionBackupViewModel extends ViewModel {
|
|||
let status;
|
||||
const hasSecretStorageKey = this._session.hasSecretStorageKey.get();
|
||||
if (hasSecretStorageKey === true) {
|
||||
status = this._session.sessionBackup ? Status.Enabled : Status.SetupKey;
|
||||
status = this._session.keyBackup ? Status.Enabled : Status.SetupKey;
|
||||
} else if (hasSecretStorageKey === false) {
|
||||
status = Status.SetupKey;
|
||||
} else {
|
||||
|
@ -59,7 +59,7 @@ export class SessionBackupViewModel extends ViewModel {
|
|||
}
|
||||
|
||||
get purpose() {
|
||||
return this.i18n`set up session backup`;
|
||||
return this.i18n`set up key backup`;
|
||||
}
|
||||
|
||||
offerDehydratedDeviceSetup() {
|
||||
|
@ -75,7 +75,7 @@ export class SessionBackupViewModel extends ViewModel {
|
|||
}
|
||||
|
||||
get backupVersion() {
|
||||
return this._session.sessionBackup?.version;
|
||||
return this._session.keyBackup?.version;
|
||||
}
|
||||
|
||||
get status() {
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import {ViewModel} from "../../ViewModel.js";
|
||||
import {SessionBackupViewModel} from "./SessionBackupViewModel.js";
|
||||
import {KeyBackupViewModel} from "./KeyBackupViewModel.js";
|
||||
|
||||
class PushNotificationStatus {
|
||||
constructor() {
|
||||
|
@ -43,7 +43,7 @@ export class SettingsViewModel extends ViewModel {
|
|||
this._updateService = options.updateService;
|
||||
const {client} = options;
|
||||
this._client = client;
|
||||
this._sessionBackupViewModel = this.track(new SessionBackupViewModel(this.childOptions({session: this._session})));
|
||||
this._keyBackupViewModel = this.track(new KeyBackupViewModel(this.childOptions({session: this._session})));
|
||||
this._closeUrl = this.urlCreator.urlUntilSegment("session");
|
||||
this._estimate = null;
|
||||
this.sentImageSizeLimit = null;
|
||||
|
@ -115,8 +115,8 @@ export class SettingsViewModel extends ViewModel {
|
|||
return !!this.platform.updateService;
|
||||
}
|
||||
|
||||
get sessionBackupViewModel() {
|
||||
return this._sessionBackupViewModel;
|
||||
get keyBackupViewModel() {
|
||||
return this._keyBackupViewModel;
|
||||
}
|
||||
|
||||
get storageQuota() {
|
||||
|
|
|
@ -29,7 +29,7 @@ import {Decryption as OlmDecryption} from "./e2ee/olm/Decryption.js";
|
|||
import {Encryption as OlmEncryption} from "./e2ee/olm/Encryption.js";
|
||||
import {Decryption as MegOlmDecryption} from "./e2ee/megolm/Decryption";
|
||||
import {KeyLoader as MegOlmKeyLoader} from "./e2ee/megolm/decryption/KeyLoader";
|
||||
import {SessionBackup} from "./e2ee/megolm/SessionBackup.js";
|
||||
import {KeyBackup} from "./e2ee/megolm/keybackup/KeyBackup";
|
||||
import {Encryption as MegOlmEncryption} from "./e2ee/megolm/Encryption.js";
|
||||
import {MEGOLM_ALGORITHM} from "./e2ee/common.js";
|
||||
import {RoomEncryption} from "./e2ee/RoomEncryption.js";
|
||||
|
@ -75,7 +75,7 @@ export class Session {
|
|||
this._megolmDecryption = null;
|
||||
this._getSyncToken = () => this.syncToken;
|
||||
this._olmWorker = olmWorker;
|
||||
this._sessionBackup = null;
|
||||
this._keyBackup = null;
|
||||
this._hasSecretStorageKey = new ObservableValue(null);
|
||||
this._observedRoomStatus = new Map();
|
||||
|
||||
|
@ -91,7 +91,7 @@ export class Session {
|
|||
}
|
||||
this._createRoomEncryption = this._createRoomEncryption.bind(this);
|
||||
this._forgetArchivedRoom = this._forgetArchivedRoom.bind(this);
|
||||
this.needsSessionBackup = new ObservableValue(false);
|
||||
this.needsKeyBackup = new ObservableValue(false);
|
||||
}
|
||||
|
||||
get fingerprintKey() {
|
||||
|
@ -170,11 +170,11 @@ export class Session {
|
|||
megolmEncryption: this._megolmEncryption,
|
||||
megolmDecryption: this._megolmDecryption,
|
||||
storage: this._storage,
|
||||
sessionBackup: this._sessionBackup,
|
||||
keyBackup: this._keyBackup,
|
||||
encryptionParams,
|
||||
notifyMissingMegolmSession: () => {
|
||||
if (!this._sessionBackup) {
|
||||
this.needsSessionBackup.set(true)
|
||||
if (!this._keyBackup) {
|
||||
this.needsKeyBackup.set(true)
|
||||
}
|
||||
},
|
||||
clock: this._platform.clock
|
||||
|
@ -183,7 +183,7 @@ export class Session {
|
|||
|
||||
/**
|
||||
* Enable secret storage by providing the secret storage credential.
|
||||
* This will also see if there is a megolm session backup and try to enable that if so.
|
||||
* This will also see if there is a megolm key backup and try to enable that if so.
|
||||
*
|
||||
* @param {string} type either "passphrase" or "recoverykey"
|
||||
* @param {string} credential either the passphrase or the recovery key, depending on the type
|
||||
|
@ -193,15 +193,15 @@ export class Session {
|
|||
if (!this._olm) {
|
||||
throw new Error("olm required");
|
||||
}
|
||||
if (this._sessionBackup) {
|
||||
if (this._keyBackup) {
|
||||
return false;
|
||||
}
|
||||
const key = await ssssKeyFromCredential(type, credential, this._storage, this._platform, this._olm);
|
||||
// and create session backup, which needs to read from accountData
|
||||
// and create key backup, which needs to read from accountData
|
||||
const readTxn = await this._storage.readTxn([
|
||||
this._storage.storeNames.accountData,
|
||||
]);
|
||||
await this._createSessionBackup(key, readTxn);
|
||||
await this._createKeyBackup(key, readTxn);
|
||||
await this._writeSSSSKey(key);
|
||||
this._hasSecretStorageKey.set(true);
|
||||
return key;
|
||||
|
@ -233,21 +233,21 @@ export class Session {
|
|||
throw err;
|
||||
}
|
||||
await writeTxn.complete();
|
||||
if (this._sessionBackup) {
|
||||
if (this._keyBackup) {
|
||||
for (const room of this._rooms.values()) {
|
||||
if (room.isEncrypted) {
|
||||
room.enableSessionBackup(undefined);
|
||||
room.enableKeyBackup(undefined);
|
||||
}
|
||||
}
|
||||
this._sessionBackup?.dispose();
|
||||
this._sessionBackup = undefined;
|
||||
this._keyBackup?.dispose();
|
||||
this._keyBackup = undefined;
|
||||
}
|
||||
this._hasSecretStorageKey.set(false);
|
||||
}
|
||||
|
||||
async _createSessionBackup(ssssKey, txn) {
|
||||
async _createKeyBackup(ssssKey, txn) {
|
||||
const secretStorage = new SecretStorage({key: ssssKey, platform: this._platform});
|
||||
this._sessionBackup = await SessionBackup.fromSecretStorage(
|
||||
this._keyBackup = await KeyBackup.fromSecretStorage(
|
||||
this._platform,
|
||||
this._olm,
|
||||
secretStorage,
|
||||
|
@ -256,18 +256,18 @@ export class Session {
|
|||
this._storage,
|
||||
txn
|
||||
);
|
||||
if (this._sessionBackup) {
|
||||
if (this._keyBackup) {
|
||||
for (const room of this._rooms.values()) {
|
||||
if (room.isEncrypted) {
|
||||
room.enableSessionBackup(this._sessionBackup);
|
||||
room.enableKeyBackup(this._keyBackup);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.needsSessionBackup.set(false);
|
||||
this.needsKeyBackup.set(false);
|
||||
}
|
||||
|
||||
get sessionBackup() {
|
||||
return this._sessionBackup;
|
||||
get keyBackup() {
|
||||
return this._keyBackup;
|
||||
}
|
||||
|
||||
get hasIdentity() {
|
||||
|
@ -405,8 +405,8 @@ export class Session {
|
|||
dispose() {
|
||||
this._olmWorker?.dispose();
|
||||
this._olmWorker = undefined;
|
||||
this._sessionBackup?.dispose();
|
||||
this._sessionBackup = undefined;
|
||||
this._keyBackup?.dispose();
|
||||
this._keyBackup = undefined;
|
||||
this._megolmDecryption?.dispose();
|
||||
this._megolmDecryption = undefined;
|
||||
this._e2eeAccount?.dispose();
|
||||
|
@ -434,7 +434,7 @@ export class Session {
|
|||
await txn.complete();
|
||||
}
|
||||
// enable session backup, this requests the latest backup version
|
||||
if (!this._sessionBackup) {
|
||||
if (!this._keyBackup) {
|
||||
if (dehydratedDevice) {
|
||||
await log.wrap("SSSSKeyFromDehydratedDeviceKey", async log => {
|
||||
const ssssKey = await createSSSSKeyFromDehydratedDeviceKey(dehydratedDevice.key, this._storage, this._platform);
|
||||
|
@ -452,7 +452,7 @@ export class Session {
|
|||
const ssssKey = await ssssReadKey(txn);
|
||||
if (ssssKey) {
|
||||
// txn will end here as this does a network request
|
||||
await this._createSessionBackup(ssssKey, txn);
|
||||
await this._createKeyBackup(ssssKey, txn);
|
||||
}
|
||||
this._hasSecretStorageKey.set(!!ssssKey);
|
||||
}
|
||||
|
@ -583,8 +583,8 @@ export class Session {
|
|||
await log.wrap("deviceMsgs", log => this._deviceMessageHandler.writeSync(preparation, txn, log));
|
||||
// this should come after the deviceMessageHandler, so the room keys are already written and their
|
||||
// isBetter property has been checked
|
||||
if (this._sessionBackup) {
|
||||
this._sessionBackup.writeKeys(preparation.newRoomKeys, txn, log);
|
||||
if (this._keyBackup) {
|
||||
this._keyBackup.writeKeys(preparation.newRoomKeys, txn, log);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -623,8 +623,8 @@ export class Session {
|
|||
await log.wrap("uploadKeys", log => this._e2eeAccount.uploadKeys(this._storage, false, log));
|
||||
}
|
||||
}
|
||||
if (this._sessionBackup) {
|
||||
this._sessionBackup.flush();
|
||||
if (this._keyBackup) {
|
||||
this._keyBackup.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ const MIN_PRESHARE_INTERVAL = 60 * 1000; // 1min
|
|||
|
||||
// TODO: this class is a good candidate for splitting up into encryption and decryption, there doesn't seem to be much overlap
|
||||
export class RoomEncryption {
|
||||
constructor({room, deviceTracker, olmEncryption, megolmEncryption, megolmDecryption, encryptionParams, storage, sessionBackup, notifyMissingMegolmSession, clock}) {
|
||||
constructor({room, deviceTracker, olmEncryption, megolmEncryption, megolmDecryption, encryptionParams, storage, keyBackup, notifyMissingMegolmSession, clock}) {
|
||||
this._room = room;
|
||||
this._deviceTracker = deviceTracker;
|
||||
this._olmEncryption = olmEncryption;
|
||||
|
@ -39,7 +39,7 @@ export class RoomEncryption {
|
|||
// caches devices to verify events
|
||||
this._senderDeviceCache = new Map();
|
||||
this._storage = storage;
|
||||
this._sessionBackup = sessionBackup;
|
||||
this._keyBackup = keyBackup;
|
||||
this._notifyMissingMegolmSession = notifyMissingMegolmSession;
|
||||
this._clock = clock;
|
||||
this._isFlushingRoomKeyShares = false;
|
||||
|
@ -48,11 +48,11 @@ export class RoomEncryption {
|
|||
this._disposed = false;
|
||||
}
|
||||
|
||||
enableSessionBackup(sessionBackup) {
|
||||
if (this._sessionBackup && !!sessionBackup) {
|
||||
enableKeyBackup(keyBackup) {
|
||||
if (this._keyBackup && !!keyBackup) {
|
||||
return;
|
||||
}
|
||||
this._sessionBackup = sessionBackup;
|
||||
this._keyBackup = keyBackup;
|
||||
}
|
||||
|
||||
async restoreMissingSessionsFromBackup(entries, log) {
|
||||
|
@ -130,7 +130,7 @@ export class RoomEncryption {
|
|||
}));
|
||||
}
|
||||
|
||||
if (!this._sessionBackup) {
|
||||
if (!this._keyBackup) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ export class RoomEncryption {
|
|||
|
||||
async _requestMissingSessionFromBackup(senderKey, sessionId, log) {
|
||||
// show prompt to enable secret storage
|
||||
if (!this._sessionBackup) {
|
||||
if (!this._keyBackup) {
|
||||
log.set("enabled", false);
|
||||
this._notifyMissingMegolmSession();
|
||||
return;
|
||||
|
@ -182,7 +182,7 @@ export class RoomEncryption {
|
|||
log.set("id", sessionId);
|
||||
log.set("senderKey", senderKey);
|
||||
try {
|
||||
const roomKey = await this._sessionBackup.getRoomKey(this._room.id, sessionId, log);
|
||||
const roomKey = await this._keyBackup.getRoomKey(this._room.id, sessionId, log);
|
||||
if (roomKey) {
|
||||
if (roomKey.senderKey !== senderKey) {
|
||||
log.set("wrong_sender_key", roomKey.senderKey);
|
||||
|
|
|
@ -14,20 +14,20 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {StoreNames} from "../../storage/common";
|
||||
import {LRUCache} from "../../../utils/LRUCache";
|
||||
import {keyFromStorage, keyFromBackup} from "./decryption/RoomKey";
|
||||
import {MEGOLM_ALGORITHM} from "../common";
|
||||
import {StoreNames} from "../../../storage/common";
|
||||
import {LRUCache} from "../../../../utils/LRUCache";
|
||||
import {keyFromStorage, keyFromBackup} from "../decryption/RoomKey";
|
||||
import {MEGOLM_ALGORITHM} from "../../common";
|
||||
|
||||
import type {HomeServerApi} from "../../net/HomeServerApi";
|
||||
import type {IncomingRoomKey, RoomKey} from "./decryption/RoomKey";
|
||||
import type {KeyLoader} from "./decryption/KeyLoader";
|
||||
import type {SecretStorage} from "../../ssss/SecretStorage";
|
||||
import type {Storage} from "../../storage/idb/Storage";
|
||||
import type {DeviceIdentity} from "../../storage/idb/stores/DeviceIdentityStore";
|
||||
import type {ILogItem} from "../../../logging/types";
|
||||
import type {Platform} from "../../../platform/web/Platform";
|
||||
import type {Transaction} from "../../storage/idb/Transaction";
|
||||
import type {HomeServerApi} from "../../../net/HomeServerApi";
|
||||
import type {IncomingRoomKey, RoomKey} from "../decryption/RoomKey";
|
||||
import type {KeyLoader} from "../decryption/KeyLoader";
|
||||
import type {SecretStorage} from "../../../ssss/SecretStorage";
|
||||
import type {Storage} from "../../../storage/idb/Storage";
|
||||
import type {DeviceIdentity} from "../../../storage/idb/stores/DeviceIdentityStore";
|
||||
import type {ILogItem} from "../../../../logging/types";
|
||||
import type {Platform} from "../../../../platform/web/Platform";
|
||||
import type {Transaction} from "../../../storage/idb/Transaction";
|
||||
import type * as OlmNamespace from "@matrix-org/olm";
|
||||
type Olm = typeof OlmNamespace;
|
||||
|
||||
|
@ -85,7 +85,7 @@ type MegOlmSessionKeyInfo = {
|
|||
|
||||
type SessionKeyInfo = MegOlmSessionKeyInfo | {algorithm: string};
|
||||
|
||||
export class SessionBackup {
|
||||
export class KeyBackup {
|
||||
constructor(
|
||||
private readonly backupInfo: BackupInfo,
|
||||
private readonly algorithm: Curve25519,
|
||||
|
@ -187,14 +187,14 @@ export class SessionBackup {
|
|||
this.algorithm.dispose();
|
||||
}
|
||||
|
||||
static async fromSecretStorage(platform: Platform, olm: Olm, secretStorage: SecretStorage, hsApi: HomeServerApi, keyLoader: KeyLoader, storage: Storage, txn: Transaction) {
|
||||
static async fromSecretStorage(platform: Platform, olm: Olm, secretStorage: SecretStorage, hsApi: HomeServerApi, keyLoader: KeyLoader, storage: Storage, txn: Transaction): Promise<KeyBackup | undefined> {
|
||||
const base64PrivateKey = await secretStorage.readSecret("m.megolm_backup.v1", txn);
|
||||
if (base64PrivateKey) {
|
||||
const privateKey = new Uint8Array(platform.encoding.base64.decode(base64PrivateKey));
|
||||
const backupInfo = await hsApi.roomKeysVersion().response() as BackupInfo;
|
||||
if (backupInfo.algorithm === Curve25519Algorithm) {
|
||||
const algorithm = Curve25519.fromAuthData(backupInfo.auth_data, privateKey, olm);
|
||||
return new SessionBackup(backupInfo, algorithm, hsApi, keyLoader, storage, platform);
|
||||
return new KeyBackup(backupInfo, algorithm, hsApi, keyLoader, storage, platform);
|
||||
} else {
|
||||
throw new Error(`Unknown backup algorithm: ${backupInfo.algorithm}`);
|
||||
}
|
|
@ -461,11 +461,11 @@ export class BaseRoom extends EventEmitter {
|
|||
return observable;
|
||||
}
|
||||
|
||||
enableSessionBackup(sessionBackup) {
|
||||
this._roomEncryption?.enableSessionBackup(sessionBackup);
|
||||
enableKeyBackup(keyBackup) {
|
||||
this._roomEncryption?.enableKeyBackup(keyBackup);
|
||||
// TODO: do we really want to do this every time you open the app?
|
||||
if (this._timeline && sessionBackup) {
|
||||
this._platform.logger.run("enableSessionBackup", log => {
|
||||
if (this._timeline && keyBackup) {
|
||||
this._platform.logger.run("enableKeyBackup", log => {
|
||||
return this._roomEncryption.restoreMissingSessionsFromBackup(this._timeline.remoteEntries, log);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -272,7 +272,7 @@ async function clearAllStores(db: IDBDatabase, txn: IDBTransaction) {
|
|||
}
|
||||
}
|
||||
|
||||
// v15 adds the sessionsNeedingBackup store, for session backup
|
||||
// v15 adds the sessionsNeedingBackup store, for key backup
|
||||
function createSessionsNeedingBackup(db: IDBDatabase): void {
|
||||
db.createObjectStore("sessionsNeedingBackup", {keyPath: "key"});
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import {TemplateView} from "../general/TemplateView";
|
||||
import {SessionBackupSettingsView} from "../session/settings/SessionBackupSettingsView.js";
|
||||
import {KeyBackupSettingsView} from "../session/settings/KeyBackupSettingsView.js";
|
||||
|
||||
export class AccountSetupView extends TemplateView {
|
||||
render(t, vm) {
|
||||
return t.div({className: "Settings" /* hack for now to get the layout right*/}, [
|
||||
t.h3(vm.i18n`Restore your encrypted history?`),
|
||||
t.ifView(vm => vm.decryptDehydratedDeviceViewModel, vm => new SessionBackupSettingsView(vm.decryptDehydratedDeviceViewModel)),
|
||||
t.ifView(vm => vm.decryptDehydratedDeviceViewModel, vm => new KeyBackupSettingsView(vm.decryptDehydratedDeviceViewModel)),
|
||||
t.map(vm => vm.deviceDecrypted, (decrypted, t) => {
|
||||
if (decrypted) {
|
||||
return t.p(vm.i18n`That worked out, you're good to go!`);
|
||||
|
|
|
@ -26,7 +26,7 @@ export class SessionStatusView extends TemplateView {
|
|||
spinner(t, {hidden: vm => !vm.isWaiting}),
|
||||
t.p(vm => vm.statusLabel),
|
||||
t.if(vm => vm.isConnectNowShown, t => t.button({className: "link", onClick: () => vm.connectNow()}, "Retry now")),
|
||||
t.if(vm => vm.isSecretStorageShown, t => t.a({href: vm.setupSessionBackupUrl}, "Go to settings")),
|
||||
t.if(vm => vm.isSecretStorageShown, t => t.a({href: vm.setupKeyBackupUrl}, "Go to settings")),
|
||||
t.if(vm => vm.canDismiss, t => t.div({className: "end"}, t.button({className: "dismiss", onClick: () => vm.dismiss()}))),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import {TemplateView, InlineTemplateView} from "../../general/TemplateView";
|
||||
import {StaticView} from "../../general/StaticView.js";
|
||||
|
||||
export class SessionBackupSettingsView extends TemplateView {
|
||||
export class KeyBackupSettingsView extends TemplateView {
|
||||
render(t, vm) {
|
||||
return t.mapView(vm => vm.status, status => {
|
||||
switch (status) {
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import {TemplateView} from "../../general/TemplateView";
|
||||
import {SessionBackupSettingsView} from "./SessionBackupSettingsView.js"
|
||||
import {KeyBackupSettingsView} from "./KeyBackupSettingsView.js"
|
||||
|
||||
export class SettingsView extends TemplateView {
|
||||
render(t, vm) {
|
||||
|
@ -47,8 +47,8 @@ export class SettingsView extends TemplateView {
|
|||
}, vm.i18n`Log out`)),
|
||||
);
|
||||
settingNodes.push(
|
||||
t.h3("Session Backup"),
|
||||
t.view(new SessionBackupSettingsView(vm.sessionBackupViewModel))
|
||||
t.h3("Key backup"),
|
||||
t.view(new KeyBackupSettingsView(vm.keyBackupViewModel))
|
||||
);
|
||||
|
||||
settingNodes.push(
|
||||
|
|
Loading…
Reference in a new issue