Improve the UX of the login fallback when using SSO (#7152)

* Don't show the login forms if we're currently logging in with a
  password or a token.
* Submit directly the SSO login form, showing only a spinner to the
  user, in order to eliminate from the clunkiness of SSO through this
  fallback.
This commit is contained in:
Brendan Abolivier 2020-03-27 15:44:13 +01:00 committed by Richard van der Hoff
parent fb69690761
commit 84f7eaed16
3 changed files with 32 additions and 22 deletions

1
changelog.d/7152.feature Normal file
View File

@ -0,0 +1 @@
Improve the support for SSO authentication on the login fallback page.

View File

@ -9,7 +9,7 @@
<body onload="matrixLogin.onLoad()"> <body onload="matrixLogin.onLoad()">
<center> <center>
<br/> <br/>
<h1>Log in with one of the following methods</h1> <h1 id="title"></h1>
<span id="feedback" style="color: #f00"></span> <span id="feedback" style="color: #f00"></span>

View File

@ -1,37 +1,41 @@
window.matrixLogin = { window.matrixLogin = {
endpoint: location.origin + "/_matrix/client/r0/login", endpoint: location.origin + "/_matrix/client/r0/login",
serverAcceptsPassword: false, serverAcceptsPassword: false,
serverAcceptsCas: false,
serverAcceptsSso: false, serverAcceptsSso: false,
}; };
var title_pre_auth = "Log in with one of the following methods";
var title_post_auth = "Logging in...";
var submitPassword = function(user, pwd) { var submitPassword = function(user, pwd) {
console.log("Logging in with password..."); console.log("Logging in with password...");
set_title(title_post_auth);
var data = { var data = {
type: "m.login.password", type: "m.login.password",
user: user, user: user,
password: pwd, password: pwd,
}; };
$.post(matrixLogin.endpoint, JSON.stringify(data), function(response) { $.post(matrixLogin.endpoint, JSON.stringify(data), function(response) {
show_login();
matrixLogin.onLogin(response); matrixLogin.onLogin(response);
}).error(errorFunc); }).error(errorFunc);
}; };
var submitToken = function(loginToken) { var submitToken = function(loginToken) {
console.log("Logging in with login token..."); console.log("Logging in with login token...");
set_title(title_post_auth);
var data = { var data = {
type: "m.login.token", type: "m.login.token",
token: loginToken token: loginToken
}; };
$.post(matrixLogin.endpoint, JSON.stringify(data), function(response) { $.post(matrixLogin.endpoint, JSON.stringify(data), function(response) {
show_login();
matrixLogin.onLogin(response); matrixLogin.onLogin(response);
}).error(errorFunc); }).error(errorFunc);
}; };
var errorFunc = function(err) { var errorFunc = function(err) {
show_login(); // We want to show the error to the user rather than redirecting immediately to the
// SSO portal (if SSO is the only login option), so we inhibit the redirect.
show_login(true);
if (err.responseJSON && err.responseJSON.error) { if (err.responseJSON && err.responseJSON.error) {
setFeedbackString(err.responseJSON.error + " (" + err.responseJSON.errcode + ")"); setFeedbackString(err.responseJSON.error + " (" + err.responseJSON.errcode + ")");
@ -45,26 +49,33 @@ var setFeedbackString = function(text) {
$("#feedback").text(text); $("#feedback").text(text);
}; };
var show_login = function() { var show_login = function(inhibit_redirect) {
$("#loading").hide();
var this_page = window.location.origin + window.location.pathname; var this_page = window.location.origin + window.location.pathname;
$("#sso_redirect_url").val(this_page); $("#sso_redirect_url").val(this_page);
// If inhibit_redirect is false, and SSO is the only supported login method, we can
// redirect straight to the SSO page
if (matrixLogin.serverAcceptsSso) {
if (!inhibit_redirect && !matrixLogin.serverAcceptsPassword) {
$("#sso_form").submit();
return;
}
// Otherwise, show the SSO form
$("#sso_form").show();
}
if (matrixLogin.serverAcceptsPassword) { if (matrixLogin.serverAcceptsPassword) {
$("#password_flow").show(); $("#password_flow").show();
} }
if (matrixLogin.serverAcceptsSso) { if (!matrixLogin.serverAcceptsPassword && !matrixLogin.serverAcceptsSso) {
$("#sso_flow").show();
} else if (matrixLogin.serverAcceptsCas) {
$("#sso_form").attr("action", "/_matrix/client/r0/login/cas/redirect");
$("#sso_flow").show();
}
if (!matrixLogin.serverAcceptsPassword && !matrixLogin.serverAcceptsCas && !matrixLogin.serverAcceptsSso) {
$("#no_login_types").show(); $("#no_login_types").show();
} }
set_title(title_pre_auth);
$("#loading").hide();
}; };
var show_spinner = function() { var show_spinner = function() {
@ -74,17 +85,15 @@ var show_spinner = function() {
$("#loading").show(); $("#loading").show();
}; };
var set_title = function(title) {
$("#title").text(title);
};
var fetch_info = function(cb) { var fetch_info = function(cb) {
$.get(matrixLogin.endpoint, function(response) { $.get(matrixLogin.endpoint, function(response) {
var serverAcceptsPassword = false; var serverAcceptsPassword = false;
var serverAcceptsCas = false;
for (var i=0; i<response.flows.length; i++) { for (var i=0; i<response.flows.length; i++) {
var flow = response.flows[i]; var flow = response.flows[i];
if ("m.login.cas" === flow.type) {
matrixLogin.serverAcceptsCas = true;
console.log("Server accepts CAS");
}
if ("m.login.sso" === flow.type) { if ("m.login.sso" === flow.type) {
matrixLogin.serverAcceptsSso = true; matrixLogin.serverAcceptsSso = true;
console.log("Server accepts SSO"); console.log("Server accepts SSO");
@ -102,7 +111,7 @@ var fetch_info = function(cb) {
matrixLogin.onLoad = function() { matrixLogin.onLoad = function() {
fetch_info(function() { fetch_info(function() {
if (!try_token()) { if (!try_token()) {
show_login(); show_login(false);
} }
}); });
}; };