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
- In the `/help` menu, only show allowed commands
- 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
- #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() {
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();
xhr.open('GET', _converse.credentials_url, true);
xhr.setRequestHeader('Accept', "application/json, text/javascript");
xhr.onload = function () {
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 400) {
const data = JSON.parse(xhr.responseText);
resolve({
@ -63927,20 +63928,34 @@ function fetchLoginCredentials() {
'password': data.password
});
} 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();
});
}, 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() {
@ -64769,17 +64784,8 @@ _converse.initialize = async function (settings, callback) {
this.autoLogin(credentials);
} else if (this.auto_login) {
if (this.credentials_url) {
let 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);
}
const data = await getLoginCredentials();
this.autoLogin(data);
} 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).");
} 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
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
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::
{

View File

@ -483,29 +483,42 @@ async function finishInitialization () {
}
}
function fetchLoginCredentials () {
return new Promise((resolve, reject) => {
function fetchLoginCredentials (wait=0) {
return new Promise(_.debounce((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', _converse.credentials_url, true);
xhr.setRequestHeader('Accept', "application/json, text/javascript");
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 400) {
const data = JSON.parse(xhr.responseText);
resolve({
'jid': data.jid,
'password': data.password
});
} else {
xhr.onerror({});
}
};
xhr.onerror = function () {
delete _converse.connection;
_converse.api.trigger('noResumeableSession', this);
reject(new Error(xhr.responseText));
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 400) {
const data = JSON.parse(xhr.responseText);
resolve({
'jid': data.jid,
'password': data.password
});
} else {
reject(new Error(`${xhr.status}: ${xhr.responseText}`));
}
};
xhr.onerror = reject;
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);
} else if (this.auto_login) {
if (this.credentials_url) {
let data = {};
try {
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);
}
const data = await getLoginCredentials();
this.autoLogin(data);
} else if (!this.jid) {
throw new Error(
"attemptNonPreboundSession: If you use auto_login, "+

View File

@ -42160,12 +42160,13 @@ async function finishInitialization() {
}
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();
xhr.open('GET', _converse.credentials_url, true);
xhr.setRequestHeader('Accept', "application/json, text/javascript");
xhr.onload = function () {
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 400) {
const data = JSON.parse(xhr.responseText);
resolve({
@ -42173,20 +42174,34 @@ function fetchLoginCredentials() {
'password': data.password
});
} 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();
});
}, 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() {
@ -43015,17 +43030,8 @@ _converse.initialize = async function (settings, callback) {
this.autoLogin(credentials);
} else if (this.auto_login) {
if (this.credentials_url) {
let 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);
}
const data = await getLoginCredentials();
this.autoLogin(data);
} 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).");
} else {