Wed, 31 Dec 2014 07:53:36 +0100
Correct small whitespace inconsistency, lost while renaming variables.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | Components.utils.import("resource://services-sync/main.js"); |
michael@0 | 6 | Components.utils.import("resource://gre/modules/Services.jsm"); |
michael@0 | 7 | |
michael@0 | 8 | XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () { |
michael@0 | 9 | return Components.utils.import("resource://gre/modules/FxAccountsCommon.js", {}); |
michael@0 | 10 | }); |
michael@0 | 11 | |
michael@0 | 12 | const PAGE_NO_ACCOUNT = 0; |
michael@0 | 13 | const PAGE_HAS_ACCOUNT = 1; |
michael@0 | 14 | const PAGE_NEEDS_UPDATE = 2; |
michael@0 | 15 | const PAGE_PLEASE_WAIT = 3; |
michael@0 | 16 | const FXA_PAGE_LOGGED_OUT = 4; |
michael@0 | 17 | const FXA_PAGE_LOGGED_IN = 5; |
michael@0 | 18 | |
michael@0 | 19 | // Indexes into the "login status" deck. |
michael@0 | 20 | // We are in a successful verified state - everything should work! |
michael@0 | 21 | const FXA_LOGIN_VERIFIED = 0; |
michael@0 | 22 | // We have logged in to an unverified account. |
michael@0 | 23 | const FXA_LOGIN_UNVERIFIED = 1; |
michael@0 | 24 | // We are logged in locally, but the server rejected our credentials. |
michael@0 | 25 | const FXA_LOGIN_FAILED = 2; |
michael@0 | 26 | |
michael@0 | 27 | let gSyncPane = { |
michael@0 | 28 | _stringBundle: null, |
michael@0 | 29 | prefArray: ["engine.bookmarks", "engine.passwords", "engine.prefs", |
michael@0 | 30 | "engine.tabs", "engine.history"], |
michael@0 | 31 | |
michael@0 | 32 | get page() { |
michael@0 | 33 | return document.getElementById("weavePrefsDeck").selectedIndex; |
michael@0 | 34 | }, |
michael@0 | 35 | |
michael@0 | 36 | set page(val) { |
michael@0 | 37 | document.getElementById("weavePrefsDeck").selectedIndex = val; |
michael@0 | 38 | }, |
michael@0 | 39 | |
michael@0 | 40 | get _usingCustomServer() { |
michael@0 | 41 | return Weave.Svc.Prefs.isSet("serverURL"); |
michael@0 | 42 | }, |
michael@0 | 43 | |
michael@0 | 44 | needsUpdate: function () { |
michael@0 | 45 | this.page = PAGE_NEEDS_UPDATE; |
michael@0 | 46 | let label = document.getElementById("loginError"); |
michael@0 | 47 | label.value = Weave.Utils.getErrorString(Weave.Status.login); |
michael@0 | 48 | label.className = "error"; |
michael@0 | 49 | }, |
michael@0 | 50 | |
michael@0 | 51 | init: function () { |
michael@0 | 52 | // If the Service hasn't finished initializing, wait for it. |
michael@0 | 53 | let xps = Components.classes["@mozilla.org/weave/service;1"] |
michael@0 | 54 | .getService(Components.interfaces.nsISupports) |
michael@0 | 55 | .wrappedJSObject; |
michael@0 | 56 | |
michael@0 | 57 | if (xps.ready) { |
michael@0 | 58 | this._init(); |
michael@0 | 59 | return; |
michael@0 | 60 | } |
michael@0 | 61 | |
michael@0 | 62 | // it may take some time before we can determine what provider to use |
michael@0 | 63 | // and the state of that provider, so show the "please wait" page. |
michael@0 | 64 | this.page = PAGE_PLEASE_WAIT; |
michael@0 | 65 | |
michael@0 | 66 | let onUnload = function () { |
michael@0 | 67 | window.removeEventListener("unload", onUnload, false); |
michael@0 | 68 | try { |
michael@0 | 69 | Services.obs.removeObserver(onReady, "weave:service:ready"); |
michael@0 | 70 | } catch (e) {} |
michael@0 | 71 | }; |
michael@0 | 72 | |
michael@0 | 73 | let onReady = function () { |
michael@0 | 74 | Services.obs.removeObserver(onReady, "weave:service:ready"); |
michael@0 | 75 | window.removeEventListener("unload", onUnload, false); |
michael@0 | 76 | this._init(); |
michael@0 | 77 | }.bind(this); |
michael@0 | 78 | |
michael@0 | 79 | Services.obs.addObserver(onReady, "weave:service:ready", false); |
michael@0 | 80 | window.addEventListener("unload", onUnload, false); |
michael@0 | 81 | |
michael@0 | 82 | xps.ensureLoaded(); |
michael@0 | 83 | }, |
michael@0 | 84 | |
michael@0 | 85 | _init: function () { |
michael@0 | 86 | let topics = ["weave:service:login:error", |
michael@0 | 87 | "weave:service:login:finish", |
michael@0 | 88 | "weave:service:start-over:finish", |
michael@0 | 89 | "weave:service:setup-complete", |
michael@0 | 90 | "weave:service:logout:finish", |
michael@0 | 91 | FxAccountsCommon.ONVERIFIED_NOTIFICATION]; |
michael@0 | 92 | |
michael@0 | 93 | // Add the observers now and remove them on unload |
michael@0 | 94 | //XXXzpao This should use Services.obs.* but Weave's Obs does nice handling |
michael@0 | 95 | // of `this`. Fix in a followup. (bug 583347) |
michael@0 | 96 | topics.forEach(function (topic) { |
michael@0 | 97 | Weave.Svc.Obs.add(topic, this.updateWeavePrefs, this); |
michael@0 | 98 | }, this); |
michael@0 | 99 | window.addEventListener("unload", function() { |
michael@0 | 100 | topics.forEach(function (topic) { |
michael@0 | 101 | Weave.Svc.Obs.remove(topic, this.updateWeavePrefs, this); |
michael@0 | 102 | }, gSyncPane); |
michael@0 | 103 | }, false); |
michael@0 | 104 | |
michael@0 | 105 | this._stringBundle = |
michael@0 | 106 | Services.strings.createBundle("chrome://browser/locale/preferences/preferences.properties"); |
michael@0 | 107 | this.updateWeavePrefs(); |
michael@0 | 108 | }, |
michael@0 | 109 | |
michael@0 | 110 | updateWeavePrefs: function () { |
michael@0 | 111 | let service = Components.classes["@mozilla.org/weave/service;1"] |
michael@0 | 112 | .getService(Components.interfaces.nsISupports) |
michael@0 | 113 | .wrappedJSObject; |
michael@0 | 114 | // service.fxAccountsEnabled is false iff sync is already configured for |
michael@0 | 115 | // the legacy provider. |
michael@0 | 116 | if (service.fxAccountsEnabled) { |
michael@0 | 117 | // determine the fxa status... |
michael@0 | 118 | this.page = PAGE_PLEASE_WAIT; |
michael@0 | 119 | Components.utils.import("resource://gre/modules/FxAccounts.jsm"); |
michael@0 | 120 | fxAccounts.getSignedInUser().then(data => { |
michael@0 | 121 | if (!data) { |
michael@0 | 122 | this.page = FXA_PAGE_LOGGED_OUT; |
michael@0 | 123 | return; |
michael@0 | 124 | } |
michael@0 | 125 | this.page = FXA_PAGE_LOGGED_IN; |
michael@0 | 126 | // We are logged in locally, but maybe we are in a state where the |
michael@0 | 127 | // server rejected our credentials (eg, password changed on the server) |
michael@0 | 128 | let fxaLoginStatus = document.getElementById("fxaLoginStatus"); |
michael@0 | 129 | let enginesListDisabled; |
michael@0 | 130 | // Not Verfied implies login error state, so check that first. |
michael@0 | 131 | if (!data.verified) { |
michael@0 | 132 | fxaLoginStatus.selectedIndex = FXA_LOGIN_UNVERIFIED; |
michael@0 | 133 | enginesListDisabled = true; |
michael@0 | 134 | // So we think we are logged in, so login problems are next. |
michael@0 | 135 | // (Although if the Sync identity manager is still initializing, we |
michael@0 | 136 | // ignore login errors and assume all will eventually be good.) |
michael@0 | 137 | // LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in". |
michael@0 | 138 | // All other login failures are assumed to be transient and should go |
michael@0 | 139 | // away by themselves, so aren't reflected here. |
michael@0 | 140 | } else if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) { |
michael@0 | 141 | fxaLoginStatus.selectedIndex = FXA_LOGIN_FAILED; |
michael@0 | 142 | enginesListDisabled = true; |
michael@0 | 143 | // Else we must be golden (or in an error state we expect to magically |
michael@0 | 144 | // resolve itself) |
michael@0 | 145 | } else { |
michael@0 | 146 | fxaLoginStatus.selectedIndex = FXA_LOGIN_VERIFIED; |
michael@0 | 147 | enginesListDisabled = false; |
michael@0 | 148 | } |
michael@0 | 149 | document.getElementById("fxaEmailAddress1").textContent = data.email; |
michael@0 | 150 | document.getElementById("fxaEmailAddress2").textContent = data.email; |
michael@0 | 151 | document.getElementById("fxaEmailAddress3").textContent = data.email; |
michael@0 | 152 | document.getElementById("fxaSyncComputerName").value = Weave.Service.clientsEngine.localName; |
michael@0 | 153 | let engines = document.getElementById("fxaSyncEngines") |
michael@0 | 154 | for (let checkbox of engines.querySelectorAll("checkbox")) { |
michael@0 | 155 | checkbox.disabled = enginesListDisabled; |
michael@0 | 156 | } |
michael@0 | 157 | |
michael@0 | 158 | let checkbox = document.getElementById("fxa-pweng-chk"); |
michael@0 | 159 | let help = document.getElementById("fxa-pweng-help"); |
michael@0 | 160 | let allowPasswordsEngine = service.allowPasswordsEngine; |
michael@0 | 161 | |
michael@0 | 162 | if (!allowPasswordsEngine) { |
michael@0 | 163 | checkbox.checked = false; |
michael@0 | 164 | } |
michael@0 | 165 | |
michael@0 | 166 | checkbox.disabled = !allowPasswordsEngine || enginesListDisabled; |
michael@0 | 167 | help.hidden = allowPasswordsEngine || enginesListDisabled; |
michael@0 | 168 | }); |
michael@0 | 169 | // If fxAccountEnabled is false and we are in a "not configured" state, |
michael@0 | 170 | // then fxAccounts is probably fully disabled rather than just unconfigured, |
michael@0 | 171 | // so handle this case. This block can be removed once we remove support |
michael@0 | 172 | // for fxAccounts being disabled. |
michael@0 | 173 | } else if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED || |
michael@0 | 174 | Weave.Svc.Prefs.get("firstSync", "") == "notReady") { |
michael@0 | 175 | this.page = PAGE_NO_ACCOUNT; |
michael@0 | 176 | // else: sync was previously configured for the legacy provider, so we |
michael@0 | 177 | // make the "old" panels available. |
michael@0 | 178 | } else if (Weave.Status.login == Weave.LOGIN_FAILED_INVALID_PASSPHRASE || |
michael@0 | 179 | Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) { |
michael@0 | 180 | this.needsUpdate(); |
michael@0 | 181 | } else { |
michael@0 | 182 | this.page = PAGE_HAS_ACCOUNT; |
michael@0 | 183 | document.getElementById("accountName").value = Weave.Service.identity.account; |
michael@0 | 184 | document.getElementById("syncComputerName").value = Weave.Service.clientsEngine.localName; |
michael@0 | 185 | document.getElementById("tosPP").hidden = this._usingCustomServer; |
michael@0 | 186 | } |
michael@0 | 187 | }, |
michael@0 | 188 | |
michael@0 | 189 | startOver: function (showDialog) { |
michael@0 | 190 | if (showDialog) { |
michael@0 | 191 | let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING + |
michael@0 | 192 | Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL + |
michael@0 | 193 | Services.prompt.BUTTON_POS_1_DEFAULT; |
michael@0 | 194 | let buttonChoice = |
michael@0 | 195 | Services.prompt.confirmEx(window, |
michael@0 | 196 | this._stringBundle.GetStringFromName("syncUnlink.title"), |
michael@0 | 197 | this._stringBundle.GetStringFromName("syncUnlink.label"), |
michael@0 | 198 | flags, |
michael@0 | 199 | this._stringBundle.GetStringFromName("syncUnlinkConfirm.label"), |
michael@0 | 200 | null, null, null, {}); |
michael@0 | 201 | |
michael@0 | 202 | // If the user selects cancel, just bail |
michael@0 | 203 | if (buttonChoice == 1) { |
michael@0 | 204 | return; |
michael@0 | 205 | } |
michael@0 | 206 | } |
michael@0 | 207 | |
michael@0 | 208 | Weave.Service.startOver(); |
michael@0 | 209 | this.updateWeavePrefs(); |
michael@0 | 210 | }, |
michael@0 | 211 | |
michael@0 | 212 | updatePass: function () { |
michael@0 | 213 | if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) { |
michael@0 | 214 | gSyncUtils.changePassword(); |
michael@0 | 215 | } else { |
michael@0 | 216 | gSyncUtils.updatePassphrase(); |
michael@0 | 217 | } |
michael@0 | 218 | }, |
michael@0 | 219 | |
michael@0 | 220 | resetPass: function () { |
michael@0 | 221 | if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) { |
michael@0 | 222 | gSyncUtils.resetPassword(); |
michael@0 | 223 | } else { |
michael@0 | 224 | gSyncUtils.resetPassphrase(); |
michael@0 | 225 | } |
michael@0 | 226 | }, |
michael@0 | 227 | |
michael@0 | 228 | /** |
michael@0 | 229 | * Invoke the Sync setup wizard. |
michael@0 | 230 | * |
michael@0 | 231 | * @param wizardType |
michael@0 | 232 | * Indicates type of wizard to launch: |
michael@0 | 233 | * null -- regular set up wizard |
michael@0 | 234 | * "pair" -- pair a device first |
michael@0 | 235 | * "reset" -- reset sync |
michael@0 | 236 | */ |
michael@0 | 237 | openSetup: function (wizardType) { |
michael@0 | 238 | let service = Components.classes["@mozilla.org/weave/service;1"] |
michael@0 | 239 | .getService(Components.interfaces.nsISupports) |
michael@0 | 240 | .wrappedJSObject; |
michael@0 | 241 | |
michael@0 | 242 | if (service.fxAccountsEnabled) { |
michael@0 | 243 | this.openContentInBrowser("about:accounts"); |
michael@0 | 244 | } else { |
michael@0 | 245 | let win = Services.wm.getMostRecentWindow("Weave:AccountSetup"); |
michael@0 | 246 | if (win) { |
michael@0 | 247 | win.focus(); |
michael@0 | 248 | } else { |
michael@0 | 249 | window.openDialog("chrome://browser/content/sync/setup.xul", |
michael@0 | 250 | "weaveSetup", "centerscreen,chrome,resizable=no", |
michael@0 | 251 | wizardType); |
michael@0 | 252 | } |
michael@0 | 253 | } |
michael@0 | 254 | }, |
michael@0 | 255 | |
michael@0 | 256 | openContentInBrowser: function(url) { |
michael@0 | 257 | let win = Services.wm.getMostRecentWindow("navigator:browser"); |
michael@0 | 258 | if (!win) { |
michael@0 | 259 | // no window to use, so use _openLink to create a new one. We don't |
michael@0 | 260 | // always use that as it prefers to open a new window rather than use |
michael@0 | 261 | // an existing one. |
michael@0 | 262 | gSyncUtils._openLink(url); |
michael@0 | 263 | return; |
michael@0 | 264 | } |
michael@0 | 265 | win.switchToTabHavingURI(url, true); |
michael@0 | 266 | // seeing as we are doing this in a tab we close the prefs dialog. |
michael@0 | 267 | window.close(); |
michael@0 | 268 | }, |
michael@0 | 269 | |
michael@0 | 270 | signUp: function() { |
michael@0 | 271 | this.openContentInBrowser("about:accounts?action=signup"); |
michael@0 | 272 | }, |
michael@0 | 273 | |
michael@0 | 274 | signIn: function() { |
michael@0 | 275 | this.openContentInBrowser("about:accounts?action=signin"); |
michael@0 | 276 | }, |
michael@0 | 277 | |
michael@0 | 278 | reSignIn: function() { |
michael@0 | 279 | this.openContentInBrowser("about:accounts?action=reauth"); |
michael@0 | 280 | }, |
michael@0 | 281 | |
michael@0 | 282 | manageFirefoxAccount: function() { |
michael@0 | 283 | let url = Services.prefs.getCharPref("identity.fxaccounts.settings.uri"); |
michael@0 | 284 | this.openContentInBrowser(url); |
michael@0 | 285 | }, |
michael@0 | 286 | |
michael@0 | 287 | verifyFirefoxAccount: function() { |
michael@0 | 288 | Components.utils.import("resource://gre/modules/FxAccounts.jsm"); |
michael@0 | 289 | fxAccounts.resendVerificationEmail().then(() => { |
michael@0 | 290 | fxAccounts.getSignedInUser().then(data => { |
michael@0 | 291 | let sb = this._stringBundle; |
michael@0 | 292 | let title = sb.GetStringFromName("firefoxAccountsVerificationSentTitle"); |
michael@0 | 293 | let heading = sb.formatStringFromName("firefoxAccountsVerificationSentHeading", |
michael@0 | 294 | [data.email], 1); |
michael@0 | 295 | let description = sb.GetStringFromName("firefoxAccountVerificationSentDescription"); |
michael@0 | 296 | |
michael@0 | 297 | Services.prompt.alert(window, title, heading + "\n\n" + description); |
michael@0 | 298 | }); |
michael@0 | 299 | }); |
michael@0 | 300 | }, |
michael@0 | 301 | |
michael@0 | 302 | openOldSyncSupportPage: function() { |
michael@0 | 303 | let url = Services.urlFormatter.formatURLPref('app.support.baseURL') + "old-sync" |
michael@0 | 304 | this.openContentInBrowser(url); |
michael@0 | 305 | }, |
michael@0 | 306 | |
michael@0 | 307 | unlinkFirefoxAccount: function(confirm) { |
michael@0 | 308 | if (confirm) { |
michael@0 | 309 | // We use a string bundle shared with aboutAccounts. |
michael@0 | 310 | let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); |
michael@0 | 311 | let continueLabel = sb.GetStringFromName("continue.label"); |
michael@0 | 312 | let title = sb.GetStringFromName("disconnect.verify.title"); |
michael@0 | 313 | let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties"); |
michael@0 | 314 | let brandShortName = brandBundle.GetStringFromName("brandShortName"); |
michael@0 | 315 | let body = sb.GetStringFromName("disconnect.verify.heading") + |
michael@0 | 316 | "\n\n" + |
michael@0 | 317 | sb.formatStringFromName("disconnect.verify.description", |
michael@0 | 318 | [brandShortName], 1); |
michael@0 | 319 | let ps = Services.prompt; |
michael@0 | 320 | let buttonFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING) + |
michael@0 | 321 | (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL) + |
michael@0 | 322 | ps.BUTTON_POS_1_DEFAULT; |
michael@0 | 323 | let pressed = Services.prompt.confirmEx(window, title, body, buttonFlags, |
michael@0 | 324 | continueLabel, null, null, null, {}); |
michael@0 | 325 | if (pressed != 0) { // 0 is the "continue" button |
michael@0 | 326 | return; |
michael@0 | 327 | } |
michael@0 | 328 | } |
michael@0 | 329 | Components.utils.import('resource://gre/modules/FxAccounts.jsm'); |
michael@0 | 330 | fxAccounts.signOut().then(() => { |
michael@0 | 331 | this.updateWeavePrefs(); |
michael@0 | 332 | }); |
michael@0 | 333 | }, |
michael@0 | 334 | |
michael@0 | 335 | openQuotaDialog: function () { |
michael@0 | 336 | let win = Services.wm.getMostRecentWindow("Sync:ViewQuota"); |
michael@0 | 337 | if (win) { |
michael@0 | 338 | win.focus(); |
michael@0 | 339 | } else { |
michael@0 | 340 | window.openDialog("chrome://browser/content/sync/quota.xul", "", |
michael@0 | 341 | "centerscreen,chrome,dialog,modal"); |
michael@0 | 342 | } |
michael@0 | 343 | }, |
michael@0 | 344 | |
michael@0 | 345 | openAddDevice: function () { |
michael@0 | 346 | if (!Weave.Utils.ensureMPUnlocked()) { |
michael@0 | 347 | return; |
michael@0 | 348 | } |
michael@0 | 349 | |
michael@0 | 350 | let win = Services.wm.getMostRecentWindow("Sync:AddDevice"); |
michael@0 | 351 | if (win) { |
michael@0 | 352 | win.focus(); |
michael@0 | 353 | } else { |
michael@0 | 354 | window.openDialog("chrome://browser/content/sync/addDevice.xul", |
michael@0 | 355 | "syncAddDevice", "centerscreen,chrome,resizable=no"); |
michael@0 | 356 | } |
michael@0 | 357 | }, |
michael@0 | 358 | |
michael@0 | 359 | resetSync: function () { |
michael@0 | 360 | this.openSetup("reset"); |
michael@0 | 361 | }, |
michael@0 | 362 | }; |
michael@0 | 363 |