From 8b71ac900e683da110077d9ae87e6902dfb73399 Mon Sep 17 00:00:00 2001 From: Ashfame Date: Tue, 28 Feb 2023 18:58:43 +0400 Subject: [PATCH 1/4] add guest login method on HomeServerApi and Client --- src/matrix/Client.js | 28 ++++++++++++++++++++++++++++ src/matrix/net/HomeServerApi.ts | 6 ++++++ 2 files changed, 34 insertions(+) diff --git a/src/matrix/Client.js b/src/matrix/Client.js index fabb489b67..bb9041506d 100644 --- a/src/matrix/Client.js +++ b/src/matrix/Client.js @@ -148,6 +148,34 @@ export class Client { return registration; } + async doGuestLogin(homeserver) { + const currentStatus = this._status.get(); + if (currentStatus !== LoadStatus.LoginFailed && + currentStatus !== LoadStatus.NotLoading && + currentStatus !== LoadStatus.Error) { + return; + } + this._resetStatus(); + + await this._platform.logger.run("login", async log => { + this._status.set(LoadStatus.Login); + try { + const request = this._platform.request; + const hsApi = new HomeServerApi({homeserver: homeserver, request: request}); + const loginData = await hsApi.guestLogin().response(); + await this.startWithAuthData({ + accessToken: loginData.access_token, + deviceId: loginData.device_id, + userId: loginData.user_id, + homeserver: homeserver + }); + } catch (err) { + this._error = err; + this._status.set(LoadStatus.Error); + } + }); + } + /** Method to start client after registration or with given access token. * To start the client after registering, use `startWithAuthData(registration.authData)`. * `homeserver` won't be resolved or normalized using this method, diff --git a/src/matrix/net/HomeServerApi.ts b/src/matrix/net/HomeServerApi.ts index 8f168e6693..7dad31ce48 100644 --- a/src/matrix/net/HomeServerApi.ts +++ b/src/matrix/net/HomeServerApi.ts @@ -215,6 +215,12 @@ export class HomeServerApi { }, options); } + guestLogin(initialDeviceDisplayName?: string, options?: BaseRequestOptions): IHomeServerRequest { + return this._unauthedRequest("POST", this._url("/register", CS_V3_PREFIX), { kind: "guest" }, { + initial_device_displayname: initialDeviceDisplayName ? initialDeviceDisplayName : 'Guest account on ' + this._homeserver, + }); + } + createFilter(userId: string, filter: Record, options?: BaseRequestOptions): IHomeServerRequest { return this._post(`/user/${encodeURIComponent(userId)}/filter`, {}, filter, options); } From 36edfd402592cc191f182b11c9acf78731cb267e Mon Sep 17 00:00:00 2001 From: Ashfame Date: Thu, 2 Mar 2023 11:41:14 +0400 Subject: [PATCH 2/4] only create a filter for sync when not in a guest user session --- src/matrix/Session.js | 9 +++++++++ src/matrix/Sync.js | 3 ++- src/matrix/net/HomeServerApi.ts | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/matrix/Session.js b/src/matrix/Session.js index bd5824356f..daf4636233 100644 --- a/src/matrix/Session.js +++ b/src/matrix/Session.js @@ -134,6 +134,15 @@ export class Session { return this._callHandler; } + async isGuest() { + if (typeof this._guestUser !== 'undefined') { + return this._guestUser; + } + const whoami = await this._hsApi.whoami().response(); + this._guestUser = whoami.is_guest; + return Boolean(whoami.is_guest); + } + _setupCallHandler() { this._callHandler = new CallHandler({ clock: this._platform.clock, diff --git a/src/matrix/Sync.js b/src/matrix/Sync.js index d335336d29..f6b667a037 100644 --- a/src/matrix/Sync.js +++ b/src/matrix/Sync.js @@ -175,7 +175,8 @@ export class Sync { async _syncRequest(syncToken, timeout, log) { let {syncFilterId} = this._session; - if (typeof syncFilterId !== "string") { + let isGuest = await this._session.isGuest(); + if (!isGuest && typeof syncFilterId !== "string") { this._currentRequest = this._hsApi.createFilter(this._session.user.id, {room: {state: {lazy_load_members: true}}}, {log}); syncFilterId = (await this._currentRequest.response()).filter_id; } diff --git a/src/matrix/net/HomeServerApi.ts b/src/matrix/net/HomeServerApi.ts index 7dad31ce48..1c8c3e557a 100644 --- a/src/matrix/net/HomeServerApi.ts +++ b/src/matrix/net/HomeServerApi.ts @@ -221,6 +221,10 @@ export class HomeServerApi { }); } + whoami(): IHomeServerRequest { + return this._get( "/account/whoami", undefined, undefined, { prefix: CS_V3_PREFIX } ); + } + createFilter(userId: string, filter: Record, options?: BaseRequestOptions): IHomeServerRequest { return this._post(`/user/${encodeURIComponent(userId)}/filter`, {}, filter, options); } From f95684bfd31bee3487a8ba75938d69e60abd6b07 Mon Sep 17 00:00:00 2001 From: Ashfame Date: Tue, 7 Mar 2023 20:42:40 +0400 Subject: [PATCH 3/4] disable join room option for guests, and present them the login button --- .../session/room/UnknownRoomViewModel.js | 14 ++++++++++++- .../room/WorldReadableRoomViewModel.js | 21 +++++++++++++++++-- .../web/ui/css/themes/element/theme.css | 2 +- .../web/ui/session/room/UnknownRoomView.js | 4 ++-- .../ui/session/room/WorldReadableRoomView.js | 8 +++++-- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/domain/session/room/UnknownRoomViewModel.js b/src/domain/session/room/UnknownRoomViewModel.js index dc7ca34002..795caa7e15 100644 --- a/src/domain/session/room/UnknownRoomViewModel.js +++ b/src/domain/session/room/UnknownRoomViewModel.js @@ -19,23 +19,35 @@ import {ViewModel} from "../../ViewModel"; export class UnknownRoomViewModel extends ViewModel { constructor(options) { super(options); - const {roomIdOrAlias, session, isWorldReadablePromise} = options; + const {roomIdOrAlias, session, isWorldReadablePromise, guestJoinAllowed} = options; this._session = session; this.roomIdOrAlias = roomIdOrAlias; this._error = null; this._busy = false; + this._guestJoinAllowed = typeof guestJoinAllowed !== 'undefined' && guestJoinAllowed; this.checkingPreviewCapability = true; isWorldReadablePromise.then(() => { this.checkingPreviewCapability = false; this.emitChange('checkingPreviewCapability'); }) + + // join allowed for the current user/session? + this._joinAllowed = false; + this._session.isGuest().then((isGuest) => { + this._joinAllowed = isGuest ? this._guestJoinAllowed : true; + this.emitChange('joinAllowed'); + }); } get error() { return this._error?.message; } + get joinAllowed() { + return this._joinAllowed; + } + async join() { this._busy = true; this.emitChange("busy"); diff --git a/src/domain/session/room/WorldReadableRoomViewModel.js b/src/domain/session/room/WorldReadableRoomViewModel.js index 88ddede7b8..691a5151d0 100644 --- a/src/domain/session/room/WorldReadableRoomViewModel.js +++ b/src/domain/session/room/WorldReadableRoomViewModel.js @@ -4,10 +4,19 @@ export class WorldReadableRoomViewModel extends RoomViewModel { constructor(options) { options.room.isWorldReadable = true; super(options); - this._room = options.room; - this._session = options.session; + const {room, session, guestJoinAllowed} = options; + this._room = room; + this._session = session; this._error = null; this._busy = false; + this._guestJoinAllowed = typeof guestJoinAllowed !== 'undefined' && guestJoinAllowed; + + // join allowed for the current user/session? + this._joinAllowed = false; + this._session.isGuest().then((isGuest) => { + this._joinAllowed = isGuest ? this._guestJoinAllowed : true; + this.emitChange('joinAllowed'); + }); } get kind() { @@ -18,6 +27,10 @@ export class WorldReadableRoomViewModel extends RoomViewModel { return this._busy; } + get joinAllowed() { + return this._joinAllowed; + } + async join() { this._busy = true; this.emitChange("busy"); @@ -36,6 +49,10 @@ export class WorldReadableRoomViewModel extends RoomViewModel { } } + login() { + this.navigation.push("login"); + } + dispose() { super.dispose(); diff --git a/src/platform/web/ui/css/themes/element/theme.css b/src/platform/web/ui/css/themes/element/theme.css index 0e7dff12db..2c2900b648 100644 --- a/src/platform/web/ui/css/themes/element/theme.css +++ b/src/platform/web/ui/css/themes/element/theme.css @@ -1024,7 +1024,7 @@ button.link { display: inline-block; margin: 0; } -.WorldReadableRoomComposerView .joinRoomButton { +.WorldReadableRoomComposerView .joinRoomButton, .WorldReadableRoomComposerView .loginButton{ float: right; } diff --git a/src/platform/web/ui/session/room/UnknownRoomView.js b/src/platform/web/ui/session/room/UnknownRoomView.js index a9ae7b9e61..531dcdd15a 100644 --- a/src/platform/web/ui/session/room/UnknownRoomView.js +++ b/src/platform/web/ui/session/room/UnknownRoomView.js @@ -25,11 +25,11 @@ export class UnknownRoomView extends TemplateView { t.br(), vm.i18n`Want to join it?` ]), - t.button({ + t.if(vm => vm.joinAllowed, t => t.button({ className: "button-action primary", onClick: () => vm.join(), disabled: vm => vm.busy, - }, vm.i18n`Join room`), + }, vm.i18n`Join room`)), t.br(), t.if(vm => vm.checkingPreviewCapability, t => t.div({className: "checkingPreviewCapability"}, [ spinner(t), diff --git a/src/platform/web/ui/session/room/WorldReadableRoomView.js b/src/platform/web/ui/session/room/WorldReadableRoomView.js index 092e7ae075..0bdcb21150 100644 --- a/src/platform/web/ui/session/room/WorldReadableRoomView.js +++ b/src/platform/web/ui/session/room/WorldReadableRoomView.js @@ -32,11 +32,15 @@ export class WorldReadableRoomView extends TemplateView { }), t.div({className: "WorldReadableRoomComposerView"}, [ t.h3(vm => vm.i18n`Join the room to participate`), - t.button({ + t.if(vm => vm.joinAllowed, t => t.button({ className: "joinRoomButton", onClick: () => vm.join(), disabled: vm => vm.busy, - }, vm.i18n`Join Room`) + }, vm.i18n`Join Room`)), + t.if(vm => !vm.joinAllowed, t => t.button({ + className: "loginButton", + onClick: () => vm.login(), + }, vm.i18n`Login`)) ]) ]) ]); From 617ad6f9c2b1c0a68fbd82ff3b23f2bf7f5e74fd Mon Sep 17 00:00:00 2001 From: Ashfame Date: Wed, 22 Mar 2023 11:49:43 +0400 Subject: [PATCH 4/4] change Login to Log In --- src/platform/web/ui/session/room/WorldReadableRoomView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/web/ui/session/room/WorldReadableRoomView.js b/src/platform/web/ui/session/room/WorldReadableRoomView.js index 0bdcb21150..720eb4a1af 100644 --- a/src/platform/web/ui/session/room/WorldReadableRoomView.js +++ b/src/platform/web/ui/session/room/WorldReadableRoomView.js @@ -40,7 +40,7 @@ export class WorldReadableRoomView extends TemplateView { t.if(vm => !vm.joinAllowed, t => t.button({ className: "loginButton", onClick: () => vm.login(), - }, vm.i18n`Login`)) + }, vm.i18n`Log In`)) ]) ]) ]);