mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 05:10:49 +00:00
Bug 1407116 - Sync now enters the "please reconnect" state if Sync is configured but FxA is not. r=eoger
MozReview-Commit-ID: LuAdYkpe0b7 --HG-- extra : rebase_source : 0fb3ca9ef0912e61354df5ca111a169df3777526
This commit is contained in:
parent
734061ef82
commit
b5876a8b65
@ -14,6 +14,9 @@ XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function() {
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
|
||||
"resource://gre/modules/FxAccounts.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "UIState",
|
||||
"resource://services-sync/UIState.jsm");
|
||||
|
||||
const FXA_PAGE_LOGGED_OUT = 0;
|
||||
const FXA_PAGE_LOGGED_IN = 1;
|
||||
|
||||
@ -112,27 +115,13 @@ var gSyncPane = {
|
||||
},
|
||||
|
||||
_init() {
|
||||
let topics = ["weave:service:login:error",
|
||||
"weave:service:login:finish",
|
||||
"weave:service:start-over:finish",
|
||||
"weave:service:setup-complete",
|
||||
"weave:service:logout:finish",
|
||||
FxAccountsCommon.ONVERIFIED_NOTIFICATION,
|
||||
FxAccountsCommon.ONLOGIN_NOTIFICATION,
|
||||
FxAccountsCommon.ON_ACCOUNT_STATE_CHANGE_NOTIFICATION,
|
||||
FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION,
|
||||
];
|
||||
// Add the observers now and remove them on unload
|
||||
// XXXzpao This should use Services.obs.* but Weave's Obs does nice handling
|
||||
// of `this`. Fix in a followup. (bug 583347)
|
||||
topics.forEach(function(topic) {
|
||||
Weave.Svc.Obs.add(topic, this.updateWeavePrefs, this);
|
||||
}, this);
|
||||
Weave.Svc.Obs.add(UIState.ON_UPDATE, this.updateWeavePrefs, this);
|
||||
|
||||
window.addEventListener("unload", function() {
|
||||
topics.forEach(function(topic) {
|
||||
Weave.Svc.Obs.remove(topic, this.updateWeavePrefs, this);
|
||||
}, gSyncPane);
|
||||
window.addEventListener("unload", () => {
|
||||
Weave.Svc.Obs.remove(UIState.ON_UPDATE, this.updateWeavePrefs, this);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_accountsStringBundle", () => {
|
||||
@ -149,10 +138,6 @@ var gSyncPane = {
|
||||
document.getElementById("tosPP-small-ToS").setAttribute("href", Weave.Svc.Prefs.get("fxa.termsURL"));
|
||||
document.getElementById("tosPP-small-PP").setAttribute("href", Weave.Svc.Prefs.get("fxa.privacyURL"));
|
||||
|
||||
fxAccounts.promiseAccountsManageURI(this._getEntryPoint()).then(accountsManageURI => {
|
||||
document.getElementById("verifiedManage").setAttribute("href", accountsManageURI);
|
||||
});
|
||||
|
||||
fxAccounts.promiseAccountsSignUpURI(this._getEntryPoint()).then(signUpURI => {
|
||||
document.getElementById("noFxaSignUp").setAttribute("href", signUpURI);
|
||||
});
|
||||
@ -263,94 +248,67 @@ var gSyncPane = {
|
||||
// determine the fxa status...
|
||||
this._showLoadPage(service);
|
||||
|
||||
fxAccounts.getSignedInUser().then(data => {
|
||||
return fxAccounts.hasLocalSession().then(hasLocalSession => {
|
||||
return [data, hasLocalSession];
|
||||
});
|
||||
}).then(([data, hasLocalSession]) => {
|
||||
if (!data) {
|
||||
this.page = FXA_PAGE_LOGGED_OUT;
|
||||
return false;
|
||||
}
|
||||
this.page = FXA_PAGE_LOGGED_IN;
|
||||
// We are logged in locally, but maybe we are in a state where the
|
||||
// server rejected our credentials (eg, password changed on the server)
|
||||
let fxaLoginStatus = document.getElementById("fxaLoginStatus");
|
||||
let syncReady;
|
||||
// We need to check error states that need a re-authenticate to resolve
|
||||
// themselves first.
|
||||
if (!hasLocalSession || Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) {
|
||||
fxaLoginStatus.selectedIndex = FXA_LOGIN_FAILED;
|
||||
syncReady = false;
|
||||
} else if (!data.verified) {
|
||||
fxaLoginStatus.selectedIndex = FXA_LOGIN_UNVERIFIED;
|
||||
syncReady = false;
|
||||
// So we think we are logged in, so login problems are next.
|
||||
// (Although if the Sync identity manager is still initializing, we
|
||||
// ignore login errors and assume all will eventually be good.)
|
||||
// LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in".
|
||||
// All other login failures are assumed to be transient and should go
|
||||
// away by themselves, so aren't reflected here.
|
||||
} else {
|
||||
// We must be golden (or in an error state we expect to magically
|
||||
// resolve itself)
|
||||
fxaLoginStatus.selectedIndex = FXA_LOGIN_VERIFIED;
|
||||
syncReady = true;
|
||||
}
|
||||
fxaEmailAddressLabels.forEach((label) => {
|
||||
label.value = data.email;
|
||||
});
|
||||
this._populateComputerName(Weave.Service.clientsEngine.localName);
|
||||
let engines = document.getElementById("fxaSyncEngines");
|
||||
for (let checkbox of engines.querySelectorAll("checkbox")) {
|
||||
checkbox.disabled = !syncReady;
|
||||
}
|
||||
document.getElementById("fxaChangeDeviceName").disabled = !syncReady;
|
||||
let state = UIState.get();
|
||||
if (state.status == UIState.STATUS_NOT_CONFIGURED) {
|
||||
this.page = FXA_PAGE_LOGGED_OUT;
|
||||
return;
|
||||
}
|
||||
this.page = FXA_PAGE_LOGGED_IN;
|
||||
// We are logged in locally, but maybe we are in a state where the
|
||||
// server rejected our credentials (eg, password changed on the server)
|
||||
let fxaLoginStatus = document.getElementById("fxaLoginStatus");
|
||||
let syncReady = false; // Is sync able to actually sync?
|
||||
// We need to check error states that need a re-authenticate to resolve
|
||||
// themselves first.
|
||||
if (state.status == UIState.STATUS_LOGIN_FAILED) {
|
||||
fxaLoginStatus.selectedIndex = FXA_LOGIN_FAILED;
|
||||
} else if (state.status == UIState.STATUS_NOT_VERIFIED) {
|
||||
fxaLoginStatus.selectedIndex = FXA_LOGIN_UNVERIFIED;
|
||||
} else {
|
||||
// We must be golden (or in an error state we expect to magically
|
||||
// resolve itself)
|
||||
fxaLoginStatus.selectedIndex = FXA_LOGIN_VERIFIED;
|
||||
syncReady = true;
|
||||
}
|
||||
fxaEmailAddressLabels.forEach((label) => {
|
||||
label.value = state.email;
|
||||
});
|
||||
this._populateComputerName(Weave.Service.clientsEngine.localName);
|
||||
let engines = document.getElementById("fxaSyncEngines");
|
||||
for (let checkbox of engines.querySelectorAll("checkbox")) {
|
||||
checkbox.disabled = !syncReady;
|
||||
}
|
||||
document.getElementById("fxaChangeDeviceName").disabled = !syncReady;
|
||||
|
||||
// Clear the profile image (if any) of the previously logged in account.
|
||||
document.querySelector("#fxaLoginVerified > .fxaProfileImage").style.removeProperty("list-style-image");
|
||||
// Clear the profile image (if any) of the previously logged in account.
|
||||
document.querySelector("#fxaLoginVerified > .fxaProfileImage").style.removeProperty("list-style-image");
|
||||
|
||||
// If the account is verified the next promise in the chain will
|
||||
// fetch profile data.
|
||||
return data.verified;
|
||||
}).then(isVerified => {
|
||||
if (isVerified) {
|
||||
return fxAccounts.getSignedInUserProfile();
|
||||
}
|
||||
return null;
|
||||
}).then(data => {
|
||||
let fxaLoginStatus = document.getElementById("fxaLoginStatus");
|
||||
if (data) {
|
||||
if (data.displayName) {
|
||||
fxaLoginStatus.setAttribute("hasName", true);
|
||||
displayNameLabel.hidden = false;
|
||||
displayNameLabel.textContent = data.displayName;
|
||||
} else {
|
||||
fxaLoginStatus.removeAttribute("hasName");
|
||||
if (state.displayName) {
|
||||
fxaLoginStatus.setAttribute("hasName", true);
|
||||
displayNameLabel.hidden = false;
|
||||
displayNameLabel.textContent = state.displayName;
|
||||
} else {
|
||||
fxaLoginStatus.removeAttribute("hasName");
|
||||
}
|
||||
if (state.avatarURL) {
|
||||
let bgImage = "url(\"" + state.avatarURL + "\")";
|
||||
let profileImageElement = document.querySelector("#fxaLoginVerified > .fxaProfileImage");
|
||||
profileImageElement.style.listStyleImage = bgImage;
|
||||
|
||||
let img = new Image();
|
||||
img.onerror = () => {
|
||||
// Clear the image if it has trouble loading. Since this callback is asynchronous
|
||||
// we check to make sure the image is still the same before we clear it.
|
||||
if (profileImageElement.style.listStyleImage === bgImage) {
|
||||
profileImageElement.style.removeProperty("list-style-image");
|
||||
}
|
||||
if (data.avatar) {
|
||||
let bgImage = "url(\"" + data.avatar + "\")";
|
||||
let profileImageElement = document.querySelector("#fxaLoginVerified > .fxaProfileImage");
|
||||
profileImageElement.style.listStyleImage = bgImage;
|
||||
|
||||
let img = new Image();
|
||||
img.onerror = () => {
|
||||
// Clear the image if it has trouble loading. Since this callback is asynchronous
|
||||
// we check to make sure the image is still the same before we clear it.
|
||||
if (profileImageElement.style.listStyleImage === bgImage) {
|
||||
profileImageElement.style.removeProperty("list-style-image");
|
||||
}
|
||||
};
|
||||
img.src = data.avatar;
|
||||
}
|
||||
} else {
|
||||
fxaLoginStatus.removeAttribute("hasName");
|
||||
}
|
||||
}, err => {
|
||||
FxAccountsCommon.log.error(err);
|
||||
}).catch(err => {
|
||||
// If we get here something's really busted
|
||||
Cu.reportError(String(err));
|
||||
};
|
||||
img.src = state.avatarURL;
|
||||
}
|
||||
// The "manage account" link embeds the uid, so we need to update this
|
||||
// if the account state changes.
|
||||
fxAccounts.promiseAccountsManageURI(this._getEntryPoint()).then(accountsManageURI => {
|
||||
document.getElementById("verifiedManage").setAttribute("href", accountsManageURI);
|
||||
});
|
||||
},
|
||||
|
||||
@ -385,7 +343,13 @@ var gSyncPane = {
|
||||
},
|
||||
|
||||
async reSignIn() {
|
||||
const url = await fxAccounts.promiseAccountsForceSigninURI(this._getEntryPoint());
|
||||
// There's a bit of an edge-case here - we might be forcing reauth when we've
|
||||
// lost the FxA account data - in which case we'll not get a URL as the re-auth
|
||||
// URL embeds account info and the server endpoint complains if we don't
|
||||
// supply it - So we just use the regular "sign in" URL in that case.
|
||||
let entryPoint = this._getEntryPoint();
|
||||
const url = (await fxAccounts.promiseAccountsForceSigninURI(entryPoint)) ||
|
||||
(await fxAccounts.promiseAccountsSignInURI(entryPoint));
|
||||
this.replaceTabWithUrl(url);
|
||||
},
|
||||
|
||||
|
@ -144,7 +144,17 @@ const UIStateInternal = {
|
||||
async _populateWithUserData(state, userData) {
|
||||
let status;
|
||||
if (!userData) {
|
||||
status = STATUS_NOT_CONFIGURED;
|
||||
// If Sync thinks it is configured but there's no FxA user, then we
|
||||
// want to enter the "login failed" state so the user can get
|
||||
// reconfigured.
|
||||
let syncUserName = Services.prefs.getStringPref("services.sync.username", "");
|
||||
if (syncUserName) {
|
||||
state.email = syncUserName;
|
||||
status = STATUS_LOGIN_FAILED;
|
||||
} else {
|
||||
// everyone agrees nothing is configured.
|
||||
status = STATUS_NOT_CONFIGURED;
|
||||
}
|
||||
} else {
|
||||
let loginFailed = await this._loginFailed();
|
||||
if (loginFailed) {
|
||||
|
@ -69,6 +69,34 @@ add_task(async function test_refreshState_signedin() {
|
||||
UIStateInternal.fxAccounts = fxAccountsOrig;
|
||||
});
|
||||
|
||||
add_task(async function test_refreshState_syncButNoFxA() {
|
||||
UIState.reset();
|
||||
const fxAccountsOrig = UIStateInternal.fxAccounts;
|
||||
|
||||
const now = new Date().toString();
|
||||
Services.prefs.setStringPref("services.sync.lastSync", now);
|
||||
Services.prefs.setStringPref("services.sync.username", "test@test.com");
|
||||
UIStateInternal.syncing = false;
|
||||
|
||||
UIStateInternal.fxAccounts = {
|
||||
getSignedInUser: () => Promise.resolve(null),
|
||||
};
|
||||
|
||||
let state = await UIState.refresh();
|
||||
|
||||
equal(state.status, UIState.STATUS_LOGIN_FAILED);
|
||||
equal(state.email, "test@test.com");
|
||||
equal(state.displayName, undefined);
|
||||
equal(state.avatarURL, undefined);
|
||||
equal(state.lastSync, undefined); // only set when STATUS_SIGNED_IN.
|
||||
equal(state.syncing, false);
|
||||
|
||||
UIStateInternal.fxAccounts = fxAccountsOrig;
|
||||
Services.prefs.clearUserPref("services.sync.lastSync");
|
||||
Services.prefs.clearUserPref("services.sync.username");
|
||||
|
||||
});
|
||||
|
||||
add_task(async function test_refreshState_signedin_profile_unavailable() {
|
||||
UIState.reset();
|
||||
const fxAccountsOrig = UIStateInternal.fxAccounts;
|
||||
|
Loading…
x
Reference in New Issue
Block a user