From f998041748bdf49ae4c0b6599c75c718ca6b286d Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Tue, 26 Oct 2021 12:49:31 +0200 Subject: [PATCH] add logout button in settings --- src/domain/session/SessionViewModel.js | 2 +- .../session/settings/SettingsViewModel.js | 26 ++++++++++++++++--- src/matrix/Session.js | 5 ++++ src/matrix/SessionContainer.js | 22 +++++++++++++--- src/matrix/net/HomeServerApi.js | 4 +++ .../web/ui/session/settings/SettingsView.js | 6 ++++- 6 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/domain/session/SessionViewModel.js b/src/domain/session/SessionViewModel.js index 83b7f1af..6aee0d8d 100644 --- a/src/domain/session/SessionViewModel.js +++ b/src/domain/session/SessionViewModel.js @@ -230,7 +230,7 @@ export class SessionViewModel extends ViewModel { } if (settingsOpen) { this._settingsViewModel = this.track(new SettingsViewModel(this.childOptions({ - session: this._sessionContainer.session, + sessionContainer: this._sessionContainer, }))); this._settingsViewModel.load(); } diff --git a/src/domain/session/settings/SettingsViewModel.js b/src/domain/session/settings/SettingsViewModel.js index ddb9ac47..9afd2888 100644 --- a/src/domain/session/settings/SettingsViewModel.js +++ b/src/domain/session/settings/SettingsViewModel.js @@ -41,18 +41,36 @@ export class SettingsViewModel extends ViewModel { constructor(options) { super(options); this._updateService = options.updateService; - const session = options.session; - this._session = session; - this._sessionBackupViewModel = this.track(new SessionBackupViewModel(this.childOptions({session}))); + const {sessionContainer} = options; + this._sessionContainer = sessionContainer; + this._sessionBackupViewModel = this.track(new SessionBackupViewModel(this.childOptions({session: this._session}))); this._closeUrl = this.urlCreator.urlUntilSegment("session"); this._estimate = null; - this.sentImageSizeLimit = null; this.minSentImageSizeLimit = 400; this.maxSentImageSizeLimit = 4000; this.pushNotifications = new PushNotificationStatus(); + this._isLoggingOut = false; } + get _session() { + return this._sessionContainer.session; + } + + logout() { + return this.logger.run("logout", async log => { + this._isLoggingOut = true; + this.emitChange("isLoggingOut"); + try { + await this._session.logout(log); + } catch (err) {} + await this._sessionContainer.deleteSession(log); + this.navigation.push("session", true); + }); + } + + get isLoggingOut() { return this._isLoggingOut; } + setSentImageSizeLimit(size) { if (size > this.maxSentImageSizeLimit || size < this.minSentImageSizeLimit) { this.sentImageSizeLimit = null; diff --git a/src/matrix/Session.js b/src/matrix/Session.js index 7047171e..235ff3b1 100644 --- a/src/matrix/Session.js +++ b/src/matrix/Session.js @@ -106,6 +106,11 @@ export class Session { return this._sessionInfo.userId; } + async logout(log = undefined) { + const response = await this._hsApi.logout({log}).response(); + console.log("logout", response); + } + // called once this._e2eeAccount is assigned _setupEncryption() { // TODO: this should all go in a wrapper in e2ee/ that is bootstrapped by passing in the account diff --git a/src/matrix/SessionContainer.js b/src/matrix/SessionContainer.js index 899b07ed..ef76971a 100644 --- a/src/matrix/SessionContainer.js +++ b/src/matrix/SessionContainer.js @@ -252,7 +252,9 @@ export class SessionContainer { } }); await log.wrap("wait first sync", () => this._waitForFirstSync()); - + if (this._isDisposed) { + return; + } this._status.set(LoadStatus.Ready); // if the sync failed, and then the reconnector @@ -261,6 +263,9 @@ export class SessionContainer { // to prevent an extra /versions request if (!this._sessionStartedByReconnector) { const lastVersionsResponse = await hsApi.versions({timeout: 10000, log}).response(); + if (this._isDisposed) { + return; + } // log as ref as we don't want to await it await log.wrap("session start", log => this._session.start(lastVersionsResponse, log)); } @@ -322,11 +327,16 @@ export class SessionContainer { return this._reconnector; } + get _isDisposed() { + return !this._reconnector; + } + dispose() { if (this._reconnectSubscription) { this._reconnectSubscription(); this._reconnectSubscription = null; } + this._reconnector = null; if (this._requestScheduler) { this._requestScheduler.stop(); } @@ -346,13 +356,17 @@ export class SessionContainer { } } - async deleteSession() { + async deleteSession(log) { if (this._sessionId) { + // need to dispose first, so the storage is closed, + // and also first sync finishing won't call Session.start anymore, + // which assumes that the storage works. + this.dispose(); // if one fails, don't block the other from trying // also, run in parallel await Promise.all([ - this._platform.storageFactory.delete(this._sessionId), - this._platform.sessionInfoStorage.delete(this._sessionId), + log.wrap("storageFactory", () => this._platform.storageFactory.delete(this._sessionId)), + log.wrap("sessionInfoStorage", () => this._platform.sessionInfoStorage.delete(this._sessionId)), ]); this._sessionId = null; } diff --git a/src/matrix/net/HomeServerApi.js b/src/matrix/net/HomeServerApi.js index 4b53b28b..c9beb00d 100644 --- a/src/matrix/net/HomeServerApi.js +++ b/src/matrix/net/HomeServerApi.js @@ -225,6 +225,10 @@ export class HomeServerApi { forget(roomId, options = null) { return this._post(`/rooms/${encodeURIComponent(roomId)}/forget`, null, null, options); } + + logout(options = null) { + return this._post(`/logout`, null, null, options); + } } import {Request as MockRequest} from "../../mocks/Request.js"; diff --git a/src/platform/web/ui/session/settings/SettingsView.js b/src/platform/web/ui/session/settings/SettingsView.js index 8fbc6812..afb4499d 100644 --- a/src/platform/web/ui/session/settings/SettingsView.js +++ b/src/platform/web/ui/session/settings/SettingsView.js @@ -40,7 +40,11 @@ export class SettingsView extends TemplateView { t.h3("Session"), row(t, vm.i18n`User ID`, vm.userId), row(t, vm.i18n`Session ID`, vm.deviceId, "code"), - row(t, vm.i18n`Session key`, vm.fingerprintKey, "code") + row(t, vm.i18n`Session key`, vm.fingerprintKey, "code"), + row(t, "", t.button({ + onClick: () => vm.logout(), + disabled: vm => vm.isLoggingOut + }, "Logout")) ); settingNodes.push( t.h3("Session Backup"),