Only generate the auth URL and start the login flow on click

This commit is contained in:
Quentin Gliech 2022-03-03 13:43:16 +01:00
parent c9b1c72d5b
commit dac68f362a
No known key found for this signature in database
GPG Key ID: 22D62B84552719FC
3 changed files with 23 additions and 16 deletions

View File

@ -116,8 +116,8 @@ export class LoginViewModel extends ViewModel {
this._startOIDCLoginViewModel = this.track( this._startOIDCLoginViewModel = this.track(
new StartOIDCLoginViewModel(this.childOptions({loginOptions: this._loginOptions})) new StartOIDCLoginViewModel(this.childOptions({loginOptions: this._loginOptions}))
); );
await this._startOIDCLoginViewModel.start();
this.emitChange("startOIDCLoginViewModel"); this.emitChange("startOIDCLoginViewModel");
this._startOIDCLoginViewModel.discover();
} }
_showError(message) { _showError(message) {
@ -129,6 +129,7 @@ export class LoginViewModel extends ViewModel {
this._isBusy = status; this._isBusy = status;
this._passwordLoginViewModel?.setBusy(status); this._passwordLoginViewModel?.setBusy(status);
this._startSSOLoginViewModel?.setBusy(status); this._startSSOLoginViewModel?.setBusy(status);
this.startOIDCLoginViewModel?.setBusy(status);
this.emitChange("isBusy"); this.emitChange("isBusy");
} }
@ -246,7 +247,7 @@ export class LoginViewModel extends ViewModel {
if (this._loginOptions) { if (this._loginOptions) {
if (this._loginOptions.sso) { this._showSSOLogin(); } if (this._loginOptions.sso) { this._showSSOLogin(); }
if (this._loginOptions.password) { this._showPasswordLogin(); } 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) { if (!this._loginOptions.sso && !this._loginOptions.password && !this._loginOptions.oidc) {
this._showError("This homeserver supports neither SSO nor password based login flows"); this._showError("This homeserver supports neither SSO nor password based login flows");
} }

View File

@ -21,35 +21,39 @@ export class StartOIDCLoginViewModel extends ViewModel {
constructor(options) { constructor(options) {
super(options); super(options);
this._isBusy = true; this._isBusy = true;
this._authorizationEndpoint = null; this._issuer = options.loginOptions.oidc.issuer;
this._homeserver = options.loginOptions.homeserver;
this._api = new OidcApi({ this._api = new OidcApi({
clientId: "hydrogen-web", clientId: "hydrogen-web",
issuer: options.loginOptions.oidc.issuer, issuer: this._issuer,
request: this.platform.request, request: this.platform.request,
encoding: this.platform.encoding, encoding: this.platform.encoding,
}); });
this._homeserver = options.loginOptions.homeserver;
} }
get isBusy() { return this._isBusy; } 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"); const p = this._api.generateParams("openid");
await Promise.all([ await Promise.all([
this.platform.settingsStorage.setInt(`oidc_${p.state}_started_at`, Date.now()), 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}_nonce`, p.nonce),
this.platform.settingsStorage.setString(`oidc_${p.state}_code_verifier`, p.codeVerifier), 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}_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); const link = await this._api.authorizationEndpoint(p);
this._isBusy = false; this.platform.openUrl(link);
}
setBusy(status) {
this._isBusy = status;
this.emitChange("isBusy");
} }
} }

View File

@ -83,7 +83,9 @@ class StartOIDCLoginView extends TemplateView {
return t.div({ className: "StartOIDCLoginView" }, return t.div({ className: "StartOIDCLoginView" },
t.a({ t.a({
className: "StartOIDCLoginView_button button-action secondary", 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`) }, vm.i18n`Log in via OIDC`)
); );
} }