mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-16 17:42:15 -04:00
Implement a username picker for synapse (#8942)
The final part (for now) of my work to implement a username picker in synapse itself. The idea is that we allow `UsernameMappingProvider`s to return `localpart=None`, in which case, rather than redirecting the browser back to the client, we redirect to a username-picker resource, which allows the user to enter a username. We *then* complete the SSO flow (including doing the client permission checks). The static resources for the username picker itself (in https://github.com/matrix-org/synapse/tree/rav/username_picker/synapse/res/username_picker) are essentially lifted wholesale from https://github.com/matrix-org/matrix-synapse-saml-mozilla/tree/master/matrix_synapse_saml_mozilla/res. As the comment says, we might want to think about making them customisable, but that can be a follow-up. Fixes #8876.
This commit is contained in:
parent
5d4c330ed9
commit
28877fade9
14 changed files with 683 additions and 59 deletions
95
synapse/res/username_picker/script.js
Normal file
95
synapse/res/username_picker/script.js
Normal file
|
@ -0,0 +1,95 @@
|
|||
let inputField = document.getElementById("field-username");
|
||||
let inputForm = document.getElementById("form");
|
||||
let submitButton = document.getElementById("button-submit");
|
||||
let message = document.getElementById("message");
|
||||
|
||||
// Submit username and receive response
|
||||
function showMessage(messageText) {
|
||||
// Unhide the message text
|
||||
message.classList.remove("hidden");
|
||||
|
||||
message.textContent = messageText;
|
||||
};
|
||||
|
||||
function doSubmit() {
|
||||
showMessage("Success. Please wait a moment for your browser to redirect.");
|
||||
|
||||
// remove the event handler before re-submitting the form.
|
||||
delete inputForm.onsubmit;
|
||||
inputForm.submit();
|
||||
}
|
||||
|
||||
function onResponse(response) {
|
||||
// Display message
|
||||
showMessage(response);
|
||||
|
||||
// Enable submit button and input field
|
||||
submitButton.classList.remove('button--disabled');
|
||||
submitButton.value = "Submit";
|
||||
};
|
||||
|
||||
let allowedUsernameCharacters = RegExp("[^a-z0-9\\.\\_\\=\\-\\/]");
|
||||
function usernameIsValid(username) {
|
||||
return !allowedUsernameCharacters.test(username);
|
||||
}
|
||||
let allowedCharactersString = "lowercase letters, digits, ., _, -, /, =";
|
||||
|
||||
function buildQueryString(params) {
|
||||
return Object.keys(params)
|
||||
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
|
||||
.join('&');
|
||||
}
|
||||
|
||||
function submitUsername(username) {
|
||||
if(username.length == 0) {
|
||||
onResponse("Please enter a username.");
|
||||
return;
|
||||
}
|
||||
if(!usernameIsValid(username)) {
|
||||
onResponse("Invalid username. Only the following characters are allowed: " + allowedCharactersString);
|
||||
return;
|
||||
}
|
||||
|
||||
// if this browser doesn't support fetch, skip the availability check.
|
||||
if(!window.fetch) {
|
||||
doSubmit();
|
||||
return;
|
||||
}
|
||||
|
||||
let check_uri = 'check?' + buildQueryString({"username": username});
|
||||
fetch(check_uri, {
|
||||
// include the cookie
|
||||
"credentials": "same-origin",
|
||||
}).then((response) => {
|
||||
if(!response.ok) {
|
||||
// for non-200 responses, raise the body of the response as an exception
|
||||
return response.text().then((text) => { throw text; });
|
||||
} else {
|
||||
return response.json();
|
||||
}
|
||||
}).then((json) => {
|
||||
if(json.error) {
|
||||
throw json.error;
|
||||
} else if(json.available) {
|
||||
doSubmit();
|
||||
} else {
|
||||
onResponse("This username is not available, please choose another.");
|
||||
}
|
||||
}).catch((err) => {
|
||||
onResponse("Error checking username availability: " + err);
|
||||
});
|
||||
}
|
||||
|
||||
function clickSubmit() {
|
||||
event.preventDefault();
|
||||
if(submitButton.classList.contains('button--disabled')) { return; }
|
||||
|
||||
// Disable submit button and input field
|
||||
submitButton.classList.add('button--disabled');
|
||||
|
||||
// Submit username
|
||||
submitButton.value = "Checking...";
|
||||
submitUsername(inputField.value);
|
||||
};
|
||||
|
||||
inputForm.onsubmit = clickSubmit;
|
Loading…
Add table
Add a link
Reference in a new issue