Bug 1433823 - Fix incorrect async handling during TPS login flow. r?markh
MozReview-Commit-ID: 4mcEcBvaKd
--- a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm
+++ b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm
@@ -27,36 +27,44 @@ var Authentication = {
/**
* Check if an user has been logged in
*/
async isLoggedIn() {
return !!(await this.getSignedInUser());
},
+ async isReady() {
+ let user = await this.getSignedInUser();
+ return user && user.verified;
+ },
+
_getRestmailUsername(user) {
const restmailSuffix = "@restmail.net";
if (user.toLowerCase().endsWith(restmailSuffix)) {
return user.slice(0, -restmailSuffix.length);
}
return null;
},
async shortWaitForVerification(ms) {
- let userData = this.getSignedInUser();
+ let userData = await this.getSignedInUser();
+ let timeoutID;
+ let timeoutPromise = new Promise(resolve => {
+ timeoutID = setTimeout(() => {
+ Logger.logInfo(`Warning: no verification after ${ms}ms.`);
+ resolve();
+ }, ms);
+ });
await Promise.race([
- fxAccounts.whenVerified(userData),
- new Promise(resolve => {
- setTimeout(() => {
- Logger.logInfo(`Warning: no verification after ${ms}ms.`);
- resolve();
- }, ms);
- })
+ fxAccounts.whenVerified(userData)
+ .finally(() => clearTimeout(timeoutID)),
+ timeoutPromise,
]);
- userData = this.getSignedInUser();
+ userData = await this.getSignedInUser();
return userData && userData.verified;
},
async _openVerificationPage(uri) {
let mainWindow = Services.wm.getMostRecentWindow("navigator:browser");
let newtab = mainWindow.getBrowser().addTab(uri);
let win = mainWindow.getBrowser().getBrowserForTab(newtab);
await new Promise(resolve => {
@@ -74,19 +82,16 @@ var Authentication = {
return false;
}
Logger.logInfo("Fetching mail (from restmail) for user " + username);
let restmailURI = `https://www.restmail.net/mail/${encodeURIComponent(username)}`;
let triedAlready = new Set();
const tries = 10;
const normalWait = 2000;
for (let i = 0; i < tries; ++i) {
- if (await this.shortWaitForVerification(normalWait)) {
- return true;
- }
let resp = await fetch(restmailURI);
let messages = await resp.json();
// Sort so that the most recent emails are first.
messages.sort((a, b) => new Date(b.receivedAt) - new Date(a.receivedAt));
for (let m of messages) {
// We look for a link that has a x-link that we haven't yet tried.
if (!m.headers["x-link"] || triedAlready.has(m.headers["x-link"])) {
continue;
@@ -101,16 +106,19 @@ var Authentication = {
} catch (e) {
Logger.logInfo("Warning: Failed to follow confirmation link: " + Log.exceptionStr(e));
}
}
if (i === 0) {
// first time through after failing we'll do this.
await fxAccounts.resendVerificationEmail();
}
+ if (await this.shortWaitForVerification(normalWait)) {
+ return true;
+ }
}
// One last try.
return this.shortWaitForVerification(normalWait);
},
async deleteEmail(user) {
let username = this._getRestmailUsername(user);
if (!username) {
--- a/services/sync/tps/extensions/tps/resource/tps.jsm
+++ b/services/sync/tps/extensions/tps/resource/tps.jsm
@@ -1174,17 +1174,17 @@ var TPS = {
await this.waitForEvent("weave:service:tracking-started");
}
},
/**
* Login on the server
*/
async Login(force) {
- if ((await Authentication.isLoggedIn()) && !force) {
+ if ((await Authentication.isReady()) && !force) {
return;
}
// This might come during Authentication.signIn
this._triggeredSync = true;
Logger.logInfo("Setting client credentials and login.");
await Authentication.signIn(this.config.fx_account);
await this.waitForSetupComplete();
@@ -1212,18 +1212,20 @@ var TPS = {
// will be overwritten by Sync itself (see bug 992198), so ensure that we
// also handle it via the "weave:service:setup-complete" notification.
if (wipeAction) {
this._syncWipeAction = wipeAction;
Weave.Svc.Prefs.set("firstSync", wipeAction);
} else {
Weave.Svc.Prefs.reset("firstSync");
}
-
- this.Login(false);
+ if (!await Weave.Service.login()) {
+ // We need to complete verification.
+ await this.Login(false);
+ }
++this._syncCount;
this._triggeredSync = true;
this.StartAsyncOperation();
await Weave.Service.sync();
Logger.logInfo("Sync is complete");
},