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