Continuously retry to fetch login credentials

This commit is contained in:
JC Brand 2019-04-29 17:29:07 +02:00
parent 3290d6659f
commit d868b9a9f7
5 changed files with 96 additions and 74 deletions

View File

@ -9,6 +9,7 @@
- Don't restore a BOSH session without knowing the JID - Don't restore a BOSH session without knowing the JID
- In the `/help` menu, only show allowed commands - In the `/help` menu, only show allowed commands
- Message deduplication bugfixes and improvements - Message deduplication bugfixes and improvements
- Continuously retry (in 2s intervals) to fetch login credentials (via [credentials_url](https://conversejs.org/docs/html/configuration.html#credentials-url)) in case of failure
- #1296: `embedded` view mode shows `chatbox-navback` arrow in header - #1296: `embedded` view mode shows `chatbox-navback` arrow in header
- #1532: Converse reloads on enter pressed in the filter box - #1532: Converse reloads on enter pressed in the filter box

52
dist/converse.js vendored
View File

@ -63914,12 +63914,13 @@ async function finishInitialization() {
} }
function fetchLoginCredentials() { function fetchLoginCredentials() {
return new es6_promise_dist_es6_promise_auto__WEBPACK_IMPORTED_MODULE_3___default.a((resolve, reject) => { let wait = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return new es6_promise_dist_es6_promise_auto__WEBPACK_IMPORTED_MODULE_3___default.a(_lodash_noconflict__WEBPACK_IMPORTED_MODULE_4___default.a.debounce((resolve, reject) => {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('GET', _converse.credentials_url, true); xhr.open('GET', _converse.credentials_url, true);
xhr.setRequestHeader('Accept', "application/json, text/javascript"); xhr.setRequestHeader('Accept', "application/json, text/javascript");
xhr.onload = function () { xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 400) { if (xhr.status >= 200 && xhr.status < 400) {
const data = JSON.parse(xhr.responseText); const data = JSON.parse(xhr.responseText);
resolve({ resolve({
@ -63927,20 +63928,34 @@ function fetchLoginCredentials() {
'password': data.password 'password': data.password
}); });
} else { } else {
xhr.onerror({}); reject(new Error(`${xhr.status}: ${xhr.responseText}`));
} }
}; };
xhr.onerror = function () { xhr.onerror = reject;
delete _converse.connection;
_converse.api.trigger('noResumeableSession', this);
reject(new Error(xhr.responseText));
};
xhr.send(); xhr.send();
}); }, wait));
}
async function getLoginCredentials() {
let credentials;
let wait = 0;
while (!credentials) {
try {
credentials = await fetchLoginCredentials(wait); // eslint-disable-line no-await-in-loop
} catch (e) {
_converse.log("Could not fetch login credentials", strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.ERROR);
_converse.log(e, strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.ERROR);
} // If unsuccessful, we wait 2 seconds between subsequent attempts to
// fetch the credentials.
wait = 2000;
}
return credentials;
} }
function unregisterGlobalEventHandlers() { function unregisterGlobalEventHandlers() {
@ -64769,17 +64784,8 @@ _converse.initialize = async function (settings, callback) {
this.autoLogin(credentials); this.autoLogin(credentials);
} else if (this.auto_login) { } else if (this.auto_login) {
if (this.credentials_url) { if (this.credentials_url) {
let data = {}; const data = await getLoginCredentials();
this.autoLogin(data);
try {
data = await fetchLoginCredentials();
} catch (e) {
_converse.log("Could not fetch login credentials", strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.ERROR);
_converse.log(e, strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.ERROR);
} finally {
this.autoLogin(data);
}
} else if (!this.jid) { } else if (!this.jid) {
throw new Error("attemptNonPreboundSession: If you use auto_login, " + "you also need to give either a jid value (and if " + "applicable a password) or you need to pass in a URL " + "from where the username and password can be fetched " + "(via credentials_url)."); throw new Error("attemptNonPreboundSession: If you use auto_login, " + "you also need to give either a jid value (and if " + "applicable a password) or you need to pass in a URL " + "from where the username and password can be fetched " + "(via credentials_url).");
} else { } else {

View File

@ -563,10 +563,13 @@ It allows you to specify a URL which Converse will call when it needs to get
the username and password (or authentication token) which Converse will use the username and password (or authentication token) which Converse will use
to automatically log the user in. to automatically log the user in.
If ``auto_reconnect`` is also set to true, then Converse will automatically If ``auto_reconnect`` is also set to ``true``, then Converse will automatically
fetch new credentials from the ``credentials_url`` whenever the connection or fetch new credentials from the ``credentials_url`` whenever the connection or
session drops, and then attempt to reconnect and establish a new session. session drops, and then attempt to reconnect and establish a new session.
If the request to the ``credentials_url`` URL fails for whatever reason,
Converse will continuously retry to fetch the credentials every 2 seconds.
The server behind ``credentials_url`` should return a JSON encoded object:: The server behind ``credentials_url`` should return a JSON encoded object::
{ {

View File

@ -483,29 +483,42 @@ async function finishInitialization () {
} }
} }
function fetchLoginCredentials () { function fetchLoginCredentials (wait=0) {
return new Promise((resolve, reject) => { return new Promise(_.debounce((resolve, reject) => {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('GET', _converse.credentials_url, true); xhr.open('GET', _converse.credentials_url, true);
xhr.setRequestHeader('Accept', "application/json, text/javascript"); xhr.setRequestHeader('Accept', "application/json, text/javascript");
xhr.onload = function() { xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 400) { if (xhr.status >= 200 && xhr.status < 400) {
const data = JSON.parse(xhr.responseText); const data = JSON.parse(xhr.responseText);
resolve({ resolve({
'jid': data.jid, 'jid': data.jid,
'password': data.password 'password': data.password
}); });
} else { } else {
xhr.onerror({}); reject(new Error(`${xhr.status}: ${xhr.responseText}`));
} }
};
xhr.onerror = function () {
delete _converse.connection;
_converse.api.trigger('noResumeableSession', this);
reject(new Error(xhr.responseText));
}; };
xhr.onerror = reject;
xhr.send(); xhr.send();
}); }, wait));
}
async function getLoginCredentials () {
let credentials;
let wait = 0;
while (!credentials) {
try {
credentials = await fetchLoginCredentials(wait); // eslint-disable-line no-await-in-loop
} catch (e) {
_converse.log("Could not fetch login credentials", Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
}
// If unsuccessful, we wait 2 seconds between subsequent attempts to
// fetch the credentials.
wait = 2000;
}
return credentials;
} }
@ -1244,15 +1257,8 @@ _converse.initialize = async function (settings, callback) {
this.autoLogin(credentials); this.autoLogin(credentials);
} else if (this.auto_login) { } else if (this.auto_login) {
if (this.credentials_url) { if (this.credentials_url) {
let data = {}; const data = await getLoginCredentials();
try { this.autoLogin(data);
data = await fetchLoginCredentials();
} catch (e) {
_converse.log("Could not fetch login credentials", Strophe.LogLevel.ERROR);
_converse.log(e, Strophe.LogLevel.ERROR);
} finally {
this.autoLogin(data);
}
} else if (!this.jid) { } else if (!this.jid) {
throw new Error( throw new Error(
"attemptNonPreboundSession: If you use auto_login, "+ "attemptNonPreboundSession: If you use auto_login, "+

View File

@ -42160,12 +42160,13 @@ async function finishInitialization() {
} }
function fetchLoginCredentials() { function fetchLoginCredentials() {
return new es6_promise_dist_es6_promise_auto__WEBPACK_IMPORTED_MODULE_3___default.a((resolve, reject) => { let wait = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return new es6_promise_dist_es6_promise_auto__WEBPACK_IMPORTED_MODULE_3___default.a(_lodash_noconflict__WEBPACK_IMPORTED_MODULE_4___default.a.debounce((resolve, reject) => {
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.open('GET', _converse.credentials_url, true); xhr.open('GET', _converse.credentials_url, true);
xhr.setRequestHeader('Accept', "application/json, text/javascript"); xhr.setRequestHeader('Accept', "application/json, text/javascript");
xhr.onload = function () { xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 400) { if (xhr.status >= 200 && xhr.status < 400) {
const data = JSON.parse(xhr.responseText); const data = JSON.parse(xhr.responseText);
resolve({ resolve({
@ -42173,20 +42174,34 @@ function fetchLoginCredentials() {
'password': data.password 'password': data.password
}); });
} else { } else {
xhr.onerror({}); reject(new Error(`${xhr.status}: ${xhr.responseText}`));
} }
}; };
xhr.onerror = function () { xhr.onerror = reject;
delete _converse.connection;
_converse.api.trigger('noResumeableSession', this);
reject(new Error(xhr.responseText));
};
xhr.send(); xhr.send();
}); }, wait));
}
async function getLoginCredentials() {
let credentials;
let wait = 0;
while (!credentials) {
try {
credentials = await fetchLoginCredentials(wait); // eslint-disable-line no-await-in-loop
} catch (e) {
_converse.log("Could not fetch login credentials", strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.ERROR);
_converse.log(e, strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.ERROR);
} // If unsuccessful, we wait 2 seconds between subsequent attempts to
// fetch the credentials.
wait = 2000;
}
return credentials;
} }
function unregisterGlobalEventHandlers() { function unregisterGlobalEventHandlers() {
@ -43015,17 +43030,8 @@ _converse.initialize = async function (settings, callback) {
this.autoLogin(credentials); this.autoLogin(credentials);
} else if (this.auto_login) { } else if (this.auto_login) {
if (this.credentials_url) { if (this.credentials_url) {
let data = {}; const data = await getLoginCredentials();
this.autoLogin(data);
try {
data = await fetchLoginCredentials();
} catch (e) {
_converse.log("Could not fetch login credentials", strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.ERROR);
_converse.log(e, strophe_js__WEBPACK_IMPORTED_MODULE_0__["Strophe"].LogLevel.ERROR);
} finally {
this.autoLogin(data);
}
} else if (!this.jid) { } else if (!this.jid) {
throw new Error("attemptNonPreboundSession: If you use auto_login, " + "you also need to give either a jid value (and if " + "applicable a password) or you need to pass in a URL " + "from where the username and password can be fetched " + "(via credentials_url)."); throw new Error("attemptNonPreboundSession: If you use auto_login, " + "you also need to give either a jid value (and if " + "applicable a password) or you need to pass in a URL " + "from where the username and password can be fetched " + "(via credentials_url).");
} else { } else {