1
Fork 0

Reconnect when server complains about a username.

If a token does not specify a username, the server will request
one by failing the join message.  Disconnect from the WebSocket
in that case, and display the login dialog with the password
field invisible.
This commit is contained in:
Juliusz Chroboczek 2023-04-01 13:28:24 +02:00
parent 4c9e00d874
commit ac1dc77b30
3 changed files with 68 additions and 29 deletions

View File

@ -105,9 +105,11 @@
<label for="username">Username</label>
<input id="username" type="text" name="username"
autocomplete="username" class="form-control"/>
<div id="passwordform">
<label for="password">Password</label>
<input id="password" type="password" name="password"
autocomplete="current-password" class="form-control"/>
</div>
<label>Enable at start:</label>
<div class="present-switch">
<p class="switch-radio">

View File

@ -32,6 +32,9 @@ let groupStatus = {};
/** @type {string} */
let token = null;
/** @type {boolean} */
let connectingAgain = false;
/**
* @typedef {Object} settings
* @property {boolean} [localMute]
@ -289,6 +292,7 @@ function setConnected(connected) {
} else {
userbox.classList.add('invisible');
connectionbox.classList.remove('invisible');
if(!connectingAgain)
displayError('Disconnected', 'error');
hideVideo();
window.onresize = null;
@ -299,17 +303,28 @@ function setConnected(connected) {
* @this {ServerConnection}
*/
async function gotConnected() {
let username, credentials;
setConnected(true);
let again = connectingAgain;
connectingAgain = false;
await join(again);
}
/**
* @param {boolean} again
*/
async function join(again) {
let username = getInputElement('username').value.trim();
let credentials;
if(token) {
credentials = {
type: 'token',
token: token,
};
token = null;
if(!again)
// the first time around, we need to join with no username in
// order to give the server a chance to reply with 'need-username'.
username = null;
} else {
setConnected(true);
username = getInputElement('username').value.trim();
let pw = getInputElement('password').value;
getInputElement('password').value = '';
if(!groupStatus.authServer)
@ -324,7 +339,7 @@ async function gotConnected() {
}
try {
await this.join(group, username, credentials);
await serverConnection.join(group, username, credentials);
} catch(e) {
console.error(e);
displayError(e);
@ -2314,29 +2329,42 @@ function setTitle(title) {
* @param {Array<string>} perms
* @param {Object<string,any>} status
* @param {Object<string,any>} data
* @param {string} error
* @param {string} message
*/
async function gotJoined(kind, group, perms, status, data, message) {
async function gotJoined(kind, group, perms, status, data, error, message) {
let present = presentRequested;
presentRequested = null;
switch(kind) {
case 'fail':
if(error === 'need-username' || error === 'duplicate-username') {
setVisibility('passwordform', false);
connectingAgain = true;
} else {
token = null;
}
if(error !== 'need-username')
displayError('The server said: ' + message);
this.close();
setButtonsVisibility();
return;
case 'redirect':
this.close();
token = null;
document.location.href = message;
return;
case 'leave':
this.close();
token = null;
setButtonsVisibility();
return;
case 'join':
case 'change':
groupStatus = status;
token = null;
// don't discard endPoint and friends
for(let key in status)
groupStatus[key] = status[key];
setTitle((status && status.displayName) || capitalise(group));
displayUsername();
setButtonsVisibility();
@ -2344,11 +2372,14 @@ async function gotJoined(kind, group, perms, status, data, message) {
return;
break;
default:
token = null;
displayError('Unknown join message');
this.close();
return;
}
token = null;
let input = /** @type{HTMLTextAreaElement} */
(document.getElementById('input'));
input.placeholder = 'Type /help for help';
@ -3622,12 +3653,8 @@ document.getElementById('userform').onsubmit = async function(e) {
e.preventDefault();
if(connecting)
return;
connecting = true;
try {
await serverConnect();
} finally {
connecting = false;
}
setVisibility('passwordform', true);
if(getInputElement('presentboth').checked)
presentRequested = 'both';
@ -3635,8 +3662,15 @@ document.getElementById('userform').onsubmit = async function(e) {
presentRequested = 'mike';
else
presentRequested = null;
getInputElement('presentoff').checked = true;
// Connect to the server, gotConnected will join.
connecting = true;
try {
await serverConnect();
} finally {
connecting = false;
}
};
document.getElementById('disconnectbutton').onclick = function(e) {
@ -3759,14 +3793,15 @@ async function start() {
addFilters();
setMediaChoices(false).then(e => reflectSettings());
if(parms.has('token')) {
if(parms.has('token'))
token = parms.get('token');
if(token) {
await serverConnect();
} else if(groupStatus.authPortal) {
window.location.href = groupStatus.authPortal;
} else {
let container = document.getElementById("login-container");
container.classList.remove('invisible');
setVisibility('login-container', true);
}
setViewportHeight();
}

View File

@ -179,7 +179,7 @@ function ServerConnection() {
*
* kind is one of 'join', 'fail', 'change' or 'leave'.
*
* @type{(this: ServerConnection, kind: string, group: string, permissions: Array<string>, status: Object<string,any>, data: Object<string,any>, message: string) => void}
* @type{(this: ServerConnection, kind: string, group: string, permissions: Array<string>, status: Object<string,any>, data: Object<string,any>, error: string, message: string) => void}
*/
this.onjoined = null;
/**
@ -321,7 +321,7 @@ ServerConnection.prototype.connect = async function(url) {
sc.onuser.call(sc, id, 'delete');
}
if(sc.group && sc.onjoined)
sc.onjoined.call(sc, 'leave', sc.group, [], {}, {}, '');
sc.onjoined.call(sc, 'leave', sc.group, [], {}, {}, '', '');
sc.group = null;
sc.username = null;
if(sc.onclose)
@ -393,7 +393,7 @@ ServerConnection.prototype.connect = async function(url) {
sc.onjoined.call(sc, m.kind, m.group,
m.permissions || [],
m.status, m.data,
m.value || null);
m.error || null, m.value || null);
break;
case 'user':
switch(m.kind) {
@ -505,8 +505,10 @@ ServerConnection.prototype.join = async function(group, username, credentials, d
type: 'join',
kind: 'join',
group: group,
username: username,
};
if(typeof username !== 'undefined' && username !== null)
m.username = username;
if((typeof credentials) === 'string') {
m.password = credentials;
} else {