Bug 967313 - ensure Sync is initialized before we set the fxAccounts user. r=ttaubert.

This commit is contained in:
Mark Hammond 2014-02-05 16:09:54 +11:00
Родитель 1ff88ffb7b
Коммит 2c1822169d
3 изменённых файлов: 50 добавлений и 14 удалений

Просмотреть файл

@ -142,18 +142,23 @@ let wrapper = {
// Remember who it was so we can log out next time.
setPreviousAccountNameHash(newAccountEmail);
fxAccounts.setSignedInUser(accountData).then(
() => {
this.injectData("message", { status: "login" });
// until we sort out a better UX, just leave the jelly page in place.
// If the account email is not yet verified, it will tell the user to
// go check their email, but then it will *not* change state after
// the verification completes (the browser will begin syncing, but
// won't notify the user). If the email has already been verified,
// the jelly will say "Welcome! You are successfully signed in as
// EMAIL", but it won't then say "syncing started".
},
(err) => this.injectData("message", { status: "error", error: err })
// A sync-specific hack - we want to ensure sync has been initialized
// before we set the signed-in user.
let xps = Cc["@mozilla.org/weave/service;1"]
.getService(Ci.nsISupports)
.wrappedJSObject;
xps.whenLoaded().then(() => {
return fxAccounts.setSignedInUser(accountData);
}).then(() => {
this.injectData("message", { status: "login" });
// until we sort out a better UX, just leave the jelly page in place.
// If the account email is not yet verified, it will tell the user to
// go check their email, but then it will *not* change state after
// the verification completes (the browser will begin syncing, but
// won't notify the user). If the email has already been verified,
// the jelly will say "Welcome! You are successfully signed in as
// EMAIL", but it won't then say "syncing started".
}, (err) => this.injectData("message", { status: "error", error: err })
);
},

Просмотреть файл

@ -9,6 +9,7 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://services-sync/util.js");
const SYNC_PREFS_BRANCH = "services.sync.";
@ -25,13 +26,25 @@ const SYNC_PREFS_BRANCH = "services.sync.";
*
* If Sync is not configured, no extra Sync code is loaded. If an
* external component (say the UI) needs to interact with Sync, it
* should do something like the following:
* should use the promise-base function whenLoaded() - something like the
* following:
*
* // 1. Grab a handle to the Sync XPCOM service.
* let service = Cc["@mozilla.org/weave/service;1"]
* .getService(Components.interfaces.nsISupports)
* .wrappedJSObject;
*
* // 2. Use the .then method of the promise.
* service.whenLoaded().then(() => {
* // You are free to interact with "Weave." objects.
* return;
* });
*
* And that's it! However, if you really want to avoid promises and do it
* old-school, then
*
* // 1. Get a reference to the service as done in (1) above.
*
* // 2. Check if the service has been initialized.
* if (service.ready) {
* // You are free to interact with "Weave." objects.
@ -65,6 +78,20 @@ WeaveService.prototype = {
Weave.Service;
},
whenLoaded: function() {
if (this.ready) {
return Promise.resolve();
}
let deferred = Promise.defer();
Services.obs.addObserver(function onReady() {
Services.obs.removeObserver(onReady, "weave:service:ready");
deferred.resolve();
}, "weave:service:ready", false);
this.ensureLoaded();
return deferred.promise;
},
get fxAccountsEnabled() {
// work out what identity manager to use. This is stored in a preference;
// if the preference exists, we trust it.

Просмотреть файл

@ -164,6 +164,7 @@ this.BrowserIDManager.prototype = {
},
observe: function (subject, topic, data) {
this._log.debug("observed " + topic);
switch (topic) {
case fxAccountsCommon.ONLOGIN_NOTIFICATION:
this.initializeWithCurrentIdentity(true);
@ -409,15 +410,17 @@ this.BrowserIDManager.prototype = {
// Both Jelly and FxAccounts give us kB as hex
let kBbytes = CommonUtils.hexToBytes(userData.kB);
let headers = {"X-Client-State": this._computeXClientState(kBbytes)};
log.info("Fetching Sync token from: " + tokenServerURI);
log.info("Fetching assertion and token from: " + tokenServerURI);
function getToken(tokenServerURI, assertion) {
log.debug("Getting a token");
let deferred = Promise.defer();
let cb = function (err, token) {
if (err) {
log.info("TokenServerClient.getTokenFromBrowserIDAssertion() failed with: " + err.message);
return deferred.reject(new AuthenticationError(err.message));
} else {
log.debug("Successfully got a sync token");
return deferred.resolve(token);
}
};
@ -427,6 +430,7 @@ this.BrowserIDManager.prototype = {
}
function getAssertion() {
log.debug("Getting an assertion");
let audience = Services.io.newURI(tokenServerURI, null, null).prePath;
return fxAccounts.getAssertion(audience).then(null, err => {
if (err.code === 401) {