notify UI when we need session backup

This commit is contained in:
Bruno Windels 2020-09-17 18:00:00 +02:00
parent 06ccd74680
commit 494c5cbcf0
5 changed files with 37 additions and 7 deletions

View file

@ -31,10 +31,11 @@ const SessionStatus = createEnum(
export class SessionStatusViewModel extends ViewModel {
constructor(options) {
super(options);
const {sync, reconnector} = options;
const {sync, reconnector, session} = options;
this._sync = sync;
this._reconnector = reconnector;
this._status = this._calculateState(reconnector.connectionStatus.get(), sync.status.get());
this._session = session;
}
@ -42,10 +43,13 @@ 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.emitChange();
}));
}
get isShown() {
return this._status !== SessionStatus.Syncing;
return this._session.needsSessionBackup.get() || this._status !== SessionStatus.Syncing;
}
get statusLabel() {
@ -61,6 +65,9 @@ export class SessionStatusViewModel extends ViewModel {
case SessionStatus.SyncError:
return this.i18n`Sync failed because of ${this._sync.error}`;
}
if (this._session.needsSessionBackup.get()) {
return this.i18n`Some messages could not be decrypted. Connect to your secret storage to decrypt them.`;
}
return "";
}
@ -122,9 +129,19 @@ export class SessionStatusViewModel extends ViewModel {
return this._status === SessionStatus.Disconnected;
}
get isSecretStorageShown() {
return this._session.needsSessionBackup.get();
}
connectNow() {
if (this.isConnectNowShown) {
this._reconnector.tryNow();
}
}
enterPassphrase(passphrase) {
if (passphrase) {
this._session.enableSecretStorage("passphrase", passphrase);
}
}
}

View file

@ -26,7 +26,8 @@ export class SessionViewModel extends ViewModel {
this._session = sessionContainer.session;
this._sessionStatusViewModel = this.track(new SessionStatusViewModel(this.childOptions({
sync: sessionContainer.sync,
reconnector: sessionContainer.reconnector
reconnector: sessionContainer.reconnector,
session: sessionContainer.session,
})));
this._currentRoomTileViewModel = null;
this._currentRoomViewModel = null;

View file

@ -36,6 +36,7 @@ import {
writeKey as ssssWriteKey,
} from "./ssss/index.js";
import {SecretStorage} from "./ssss/SecretStorage.js";
import {ObservableValue} from "../observable/ObservableValue.js";
const PICKLE_KEY = "DEFAULT_KEY";
@ -74,6 +75,7 @@ export class Session {
});
}
this._createRoomEncryption = this._createRoomEncryption.bind(this);
this.needsSessionBackup = new ObservableValue(false);
}
// called once this._e2eeAccount is assigned
@ -140,6 +142,11 @@ export class Session {
storage: this._storage,
sessionBackup: this._sessionBackup,
encryptionParams,
notifyMissingMegolmSession: () => {
if (!this._sessionBackup) {
this.needsSessionBackup.set(true)
}
},
});
}
@ -185,6 +192,7 @@ export class Session {
}
}
}
this.needsSessionBackup.set(false);
}
// called after load

View file

@ -22,7 +22,7 @@ import {makeTxnId} from "../common.js";
const ENCRYPTED_TYPE = "m.room.encrypted";
export class RoomEncryption {
constructor({room, deviceTracker, olmEncryption, megolmEncryption, megolmDecryption, encryptionParams, storage, sessionBackup}) {
constructor({room, deviceTracker, olmEncryption, megolmEncryption, megolmDecryption, encryptionParams, storage, sessionBackup, notifyMissingMegolmSession}) {
this._room = room;
this._deviceTracker = deviceTracker;
this._olmEncryption = olmEncryption;
@ -38,15 +38,18 @@ export class RoomEncryption {
this._senderDeviceCache = new Map();
this._storage = storage;
this._sessionBackup = sessionBackup;
this._notifyMissingMegolmSession = notifyMissingMegolmSession;
}
enableSessionBackup(sessionBackup) {
async enableSessionBackup(sessionBackup) {
if (this._sessionBackup) {
return;
}
this._sessionBackup = sessionBackup;
// TODO: query session backup for all missing sessions so far
// can we query multiple? no, only for sessionId, all for room, or all
for(const key of this._eventIdsByMissingSession.keys()) {
const [senderKey, sessionId] = key.split("|");
await this._requestMissingSessionFromBackup(senderKey, sessionId);
}
}
notifyTimelineClosed() {

View file

@ -26,6 +26,7 @@ export class SessionStatusView extends TemplateView {
spinner(t, {hidden: vm => !vm.isWaiting}),
t.p(vm => vm.statusLabel),
t.if(vm => vm.isConnectNowShown, t.createTemplate(t => t.button({onClick: () => vm.connectNow()}, "Retry now"))),
t.if(vm => vm.isSecretStorageShown, t.createTemplate(t => t.button({onClick: () => vm.enterPassphrase(prompt("passphrase"))}, "Enter passphrase"))),
window.DEBUG ? t.button({id: "showlogs"}, "Show logs") : ""
]);
}