mirror of
https://github.com/jech/galene.git
synced 2024-11-12 19:55:59 +01:00
Force a user interaction before token login.
This avoids issues with autoplay being disabled.
This commit is contained in:
parent
14aeb125be
commit
8fe2e9ca5f
4 changed files with 55 additions and 34 deletions
4
CHANGES
4
CHANGES
|
@ -2,7 +2,9 @@ Galene 0.9.1 (unreleased)
|
|||
|
||||
* Added an example client with minimal functionality under static/example.
|
||||
* Fixed a race condition that would cause the client to run with
|
||||
undefined settings if the initial connection was extremely quick.
|
||||
undefined settings if the initial connection was extremely fast.
|
||||
* Changed the token login to force a user interaction in order to avoid
|
||||
issues with autoplay.
|
||||
* Implemented client-side timeouts (we already had one on the server side).
|
||||
* Reduced the server-side timeout.
|
||||
* Don't attempt to set the file descriptor limit, since recent versions
|
||||
|
|
|
@ -715,17 +715,17 @@ h1 {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.userform {
|
||||
.login {
|
||||
display: inline
|
||||
}
|
||||
|
||||
.userform label {
|
||||
.loginform label {
|
||||
min-width: 3em;
|
||||
display: inline-block;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.userform input[type="text"], .userform input[type="password"] {
|
||||
.loginform input[type="text"], .loginform input[type="password"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,10 +101,12 @@
|
|||
</div>
|
||||
<div class="login-container invisible" id="login-container">
|
||||
<div class="login-box">
|
||||
<form id="userform" class="userform">
|
||||
<label for="username">Username</label>
|
||||
<input id="username" type="text" name="username"
|
||||
autocomplete="username" class="form-control"/>
|
||||
<form id="loginform" class="loginform">
|
||||
<div id="userform">
|
||||
<label for="username">Username</label>
|
||||
<input id="username" type="text" name="username"
|
||||
autocomplete="username" class="form-control"/>
|
||||
</div>
|
||||
<div id="passwordform">
|
||||
<label for="password">Password</label>
|
||||
<input id="password" type="password" name="password"
|
||||
|
|
|
@ -35,8 +35,8 @@ let pwAuth = false;
|
|||
/** @type {string} */
|
||||
let token = null;
|
||||
|
||||
/** @type {boolean} */
|
||||
let connectingAgain = false;
|
||||
/** @type {string} */
|
||||
let probingState = null;
|
||||
|
||||
/**
|
||||
* @typedef {Object} settings
|
||||
|
@ -317,8 +317,6 @@ function setConnected(connected) {
|
|||
} else {
|
||||
userbox.classList.add('invisible');
|
||||
connectionbox.classList.remove('invisible');
|
||||
if(!connectingAgain)
|
||||
displayError('Disconnected', 'error');
|
||||
hideVideo();
|
||||
window.onresize = null;
|
||||
}
|
||||
|
@ -329,9 +327,7 @@ function setConnected(connected) {
|
|||
*/
|
||||
async function gotConnected() {
|
||||
setConnected(true);
|
||||
let again = connectingAgain;
|
||||
connectingAgain = false;
|
||||
await join(again);
|
||||
await join();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -352,10 +348,7 @@ function setChangePassword(username) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} again
|
||||
*/
|
||||
async function join(again) {
|
||||
async function join() {
|
||||
let username = getInputElement('username').value.trim();
|
||||
let credentials;
|
||||
if(token) {
|
||||
|
@ -364,11 +357,30 @@ async function join(again) {
|
|||
type: 'token',
|
||||
token: token,
|
||||
};
|
||||
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'.
|
||||
switch(probingState) {
|
||||
case null:
|
||||
// when logging in with a token, we need to give the user
|
||||
// a chance to interact with the page in order to enable
|
||||
// autoplay. Probe the group first in order to determine if
|
||||
// we need a username. We should really extend the protocol
|
||||
// to have a simpler protocol for probing.
|
||||
probingState = 'probing';
|
||||
username = null;
|
||||
break;
|
||||
case 'need-username':
|
||||
case 'success':
|
||||
probingState = null;
|
||||
break
|
||||
default:
|
||||
console.warn(`Unexpected probing state ${probingState}`);
|
||||
probingState = null;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(probingState !== null) {
|
||||
console.warn(`Unexpected probing state ${probingState}`);
|
||||
probingState = null;
|
||||
}
|
||||
let pw = getInputElement('password').value;
|
||||
getInputElement('password').value = '';
|
||||
if(!groupStatus.authServer) {
|
||||
|
@ -420,9 +432,9 @@ function gotClose(code, reason) {
|
|||
if(code != 1000) {
|
||||
console.warn('Socket close', code, reason);
|
||||
}
|
||||
let form = document.getElementById('userform');
|
||||
let form = document.getElementById('loginform');
|
||||
if(!(form instanceof HTMLFormElement))
|
||||
throw new Error('Bad type for userform');
|
||||
throw new Error('Bad type for loginform');
|
||||
form.active = true;
|
||||
}
|
||||
|
||||
|
@ -2471,14 +2483,13 @@ async function gotJoined(kind, group, perms, status, data, error, message) {
|
|||
|
||||
switch(kind) {
|
||||
case 'fail':
|
||||
if(error === 'need-username' || error === 'duplicate-username') {
|
||||
if(probingState === 'probing' && error === 'need-username') {
|
||||
probingState = 'need-username';
|
||||
setVisibility('passwordform', false);
|
||||
connectingAgain = true;
|
||||
} else {
|
||||
token = null;
|
||||
}
|
||||
if(error !== 'need-username')
|
||||
displayError('The server said: ' + message);
|
||||
}
|
||||
this.close();
|
||||
setButtonsVisibility();
|
||||
return;
|
||||
|
@ -2489,13 +2500,21 @@ async function gotJoined(kind, group, perms, status, data, error, message) {
|
|||
return;
|
||||
case 'leave':
|
||||
this.close();
|
||||
token = null;
|
||||
setButtonsVisibility();
|
||||
setChangePassword(null);
|
||||
return;
|
||||
case 'join':
|
||||
case 'change':
|
||||
token = null;
|
||||
if(probingState === 'probing') {
|
||||
probingState = 'success';
|
||||
setVisibility('userform', false);
|
||||
setVisibility('passwordform', false);
|
||||
this.close();
|
||||
setButtonsVisibility();
|
||||
return;
|
||||
} else {
|
||||
token = null;
|
||||
}
|
||||
// don't discard endPoint and friends
|
||||
for(let key in status)
|
||||
groupStatus[key] = status[key];
|
||||
|
@ -2515,8 +2534,6 @@ async function gotJoined(kind, group, perms, status, data, error, message) {
|
|||
return;
|
||||
}
|
||||
|
||||
token = null;
|
||||
|
||||
let input = /** @type{HTMLTextAreaElement} */
|
||||
(document.getElementById('input'));
|
||||
input.placeholder = 'Type /help for help';
|
||||
|
@ -3907,12 +3924,12 @@ function displayMessage(message) {
|
|||
return displayError(message, "info");
|
||||
}
|
||||
|
||||
document.getElementById('userform').onsubmit = async function(e) {
|
||||
document.getElementById('loginform').onsubmit = async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
let form = this;
|
||||
if(!(form instanceof HTMLFormElement))
|
||||
throw new Error('Bad type for userform');
|
||||
throw new Error('Bad type for loginform');
|
||||
|
||||
setVisibility('passwordform', true);
|
||||
|
||||
|
|
Loading…
Reference in a new issue