You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-28 05:03:59 +03:00
Don't overlap auth submissions with polls
Wait for polls to complete before submitting auth dicts, otherwise we risk the requests overlapping and both returning a 200. Also introduces a setBusy interface to interactive-auth to explicitly set the busy status, since otherwise it doesn't get set until the request actually starts.
This commit is contained in:
@@ -55,6 +55,12 @@ const MSISDN_STAGE_TYPE = "m.login.msisdn";
|
||||
* promise which resolves to the successful response or rejects with a
|
||||
* MatrixError.
|
||||
*
|
||||
* @param {function(bool): module:client.Promise} opts.setBusy
|
||||
* called whenever the interactive auth logic is busy submitting
|
||||
* information provided by the user. After this has been called with
|
||||
* true the UI should indicate that a request is in progress until it
|
||||
* is called again with false.
|
||||
*
|
||||
* @param {function(string, object?)} opts.stateUpdated
|
||||
* called when the status of the UI auth changes, ie. when the state of
|
||||
* an auth stage changes of when the auth flow moves to a new stage.
|
||||
@@ -101,6 +107,7 @@ function InteractiveAuth(opts) {
|
||||
this._matrixClient = opts.matrixClient;
|
||||
this._data = opts.authData || {};
|
||||
this._requestCallback = opts.doRequest;
|
||||
this._setBusyCallback = opts.setBusy;
|
||||
// startAuthStage included for backwards compat
|
||||
this._stateUpdatedCallback = opts.stateUpdated || opts.startAuthStage;
|
||||
this._resolveFunc = null;
|
||||
@@ -117,7 +124,9 @@ function InteractiveAuth(opts) {
|
||||
this._chosenFlow = null;
|
||||
this._currentStage = null;
|
||||
|
||||
this._polling = false;
|
||||
// if we are currently trying to submit an auth dict (which includes polling)
|
||||
// the promise the will resolve/reject when it completes
|
||||
this._submitPromise = false;
|
||||
}
|
||||
|
||||
InteractiveAuth.prototype = {
|
||||
@@ -138,7 +147,10 @@ InteractiveAuth.prototype = {
|
||||
// if we have no flows, try a request (we'll have
|
||||
// just a session ID in _data if resuming)
|
||||
if (!this._data.flows) {
|
||||
this._doRequest(this._data);
|
||||
this._setBusyCallback(true);
|
||||
this._doRequest(this._data).finally(() => {
|
||||
this._setBusyCallback(false);
|
||||
});
|
||||
} else {
|
||||
this._startNextAuthStage();
|
||||
}
|
||||
@@ -152,7 +164,9 @@ InteractiveAuth.prototype = {
|
||||
*/
|
||||
poll: async function() {
|
||||
if (!this._data.session) return;
|
||||
if (this._polling) return;
|
||||
// if we currently have a request in flight, there's no point making
|
||||
// another just to check what the status is
|
||||
if (this._submitPromise) return;
|
||||
|
||||
let authDict = {};
|
||||
if (this._currentStage == EMAIL_STAGE_TYPE) {
|
||||
@@ -173,12 +187,7 @@ InteractiveAuth.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
this._polling = true;
|
||||
try {
|
||||
await this.submitAuthDict(authDict, true);
|
||||
} finally {
|
||||
this._polling = false;
|
||||
}
|
||||
this.submitAuthDict(authDict, true);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -235,13 +244,37 @@ InteractiveAuth.prototype = {
|
||||
throw new Error("submitAuthDict() called before attemptAuth()");
|
||||
}
|
||||
|
||||
if (!background && this._setBusyCallback) {
|
||||
this._setBusyCallback(true);
|
||||
}
|
||||
|
||||
// if we're currently trying a request, wait for it to finish
|
||||
// as otherwise we can get multiple 200 responses which can mean
|
||||
// things like multiple logins for register requests.
|
||||
// (but discard any expections as we only care when its done,
|
||||
// not whether it worked or not)
|
||||
while (this._submitPromise) {
|
||||
try {
|
||||
await this._submitPromise;
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
// use the sessionid from the last request.
|
||||
const auth = {
|
||||
session: this._data.session,
|
||||
};
|
||||
utils.extend(auth, authData);
|
||||
|
||||
await this._doRequest(auth, background);
|
||||
try {
|
||||
// NB. the 'background' flag is deprecated by the setBusy
|
||||
// callback and is here for backwards compat
|
||||
this._submitPromise = this._doRequest(auth, background);
|
||||
await this._submitPromise;
|
||||
} finally {
|
||||
this._submitPromise = null;
|
||||
if (!background) this._setBusyCallback(false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user