From 4b07f048430f4e57d76af874c866a4b54af060a6 Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Thu, 3 Mar 2022 13:43:16 +0100 Subject: [PATCH] Only generate the auth URL and start the login flow on click --- src/domain/login/LoginViewModel.ts | 5 ++-- src/domain/login/StartOIDCLoginViewModel.js | 30 ++++++++++++--------- src/platform/web/ui/login/LoginView.js | 4 ++- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/domain/login/LoginViewModel.ts b/src/domain/login/LoginViewModel.ts index 55e503a9..bd225d56 100644 --- a/src/domain/login/LoginViewModel.ts +++ b/src/domain/login/LoginViewModel.ts @@ -171,8 +171,8 @@ export class LoginViewModel extends ViewModel { this._startOIDCLoginViewModel = this.track( new StartOIDCLoginViewModel(this.childOptions({loginOptions: this._loginOptions})) ); - await this._startOIDCLoginViewModel.start(); this.emitChange("startOIDCLoginViewModel"); + this._startOIDCLoginViewModel.discover(); } private _showError(message: string): void { @@ -184,6 +184,7 @@ export class LoginViewModel extends ViewModel { this._isBusy = status; this._passwordLoginViewModel?.setBusy(status); this._startSSOLoginViewModel?.setBusy(status); + this.startOIDCLoginViewModel?.setBusy(status); this.emitChange("isBusy"); } @@ -301,7 +302,7 @@ export class LoginViewModel extends ViewModel { if (this._loginOptions) { if (this._loginOptions.sso) { this._showSSOLogin(); } if (this._loginOptions.password) { this._showPasswordLogin(); } - if (this._loginOptions.oidc) { await this._showOIDCLogin(); } + if (this._loginOptions.oidc) { this._showOIDCLogin(); } if (!this._loginOptions.sso && !this._loginOptions.password && !this._loginOptions.oidc) { this._showError("This homeserver supports neither SSO nor password based login flows"); } diff --git a/src/domain/login/StartOIDCLoginViewModel.js b/src/domain/login/StartOIDCLoginViewModel.js index e742fe1c..146d81b1 100644 --- a/src/domain/login/StartOIDCLoginViewModel.js +++ b/src/domain/login/StartOIDCLoginViewModel.js @@ -21,35 +21,39 @@ export class StartOIDCLoginViewModel extends ViewModel { constructor(options) { super(options); this._isBusy = true; - this._authorizationEndpoint = null; + this._issuer = options.loginOptions.oidc.issuer; + this._homeserver = options.loginOptions.homeserver; this._api = new OidcApi({ clientId: "hydrogen-web", - issuer: options.loginOptions.oidc.issuer, + issuer: this._issuer, request: this.platform.request, encoding: this.platform.encoding, }); - this._homeserver = options.loginOptions.homeserver; } get isBusy() { return this._isBusy; } - get authorizationEndpoint() { return this._authorizationEndpoint; } - async start() { + setBusy(status) { + this._isBusy = status; + this.emitChange("isBusy"); + } + + async discover() { + // Ask for the metadata once so it gets discovered and cached + await this._api.metadata() + } + + async startOIDCLogin() { const p = this._api.generateParams("openid"); await Promise.all([ this.platform.settingsStorage.setInt(`oidc_${p.state}_started_at`, Date.now()), this.platform.settingsStorage.setString(`oidc_${p.state}_nonce`, p.nonce), this.platform.settingsStorage.setString(`oidc_${p.state}_code_verifier`, p.codeVerifier), this.platform.settingsStorage.setString(`oidc_${p.state}_homeserver`, this._homeserver), - this.platform.settingsStorage.setString(`oidc_${p.state}_issuer`, this._api.issuer), + this.platform.settingsStorage.setString(`oidc_${p.state}_issuer`, this._issuer), ]); - this._authorizationEndpoint = await this._api.authorizationEndpoint(p); - this._isBusy = false; - } - - setBusy(status) { - this._isBusy = status; - this.emitChange("isBusy"); + const link = await this._api.authorizationEndpoint(p); + this.platform.openUrl(link); } } diff --git a/src/platform/web/ui/login/LoginView.js b/src/platform/web/ui/login/LoginView.js index ee8bf169..116c82cd 100644 --- a/src/platform/web/ui/login/LoginView.js +++ b/src/platform/web/ui/login/LoginView.js @@ -83,7 +83,9 @@ class StartOIDCLoginView extends TemplateView { return t.div({ className: "StartOIDCLoginView" }, t.a({ className: "StartOIDCLoginView_button button-action secondary", - href: vm => (vm.isBusy ? "#" : vm.authorizationEndpoint), + type: "button", + onClick: () => vm.startOIDCLogin(), + disabled: vm => vm.isBusy }, vm.i18n`Log in via OIDC`) ); }