browser/base/content/sync/utils.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/base/content/sync/utils.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,233 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +// Equivalent to 0600 permissions; used for saved Sync Recovery Key.
     1.9 +// This constant can be replaced when the equivalent values are available to
    1.10 +// chrome JS; see Bug 433295 and Bug 757351.
    1.11 +const PERMISSIONS_RWUSR = 0x180;
    1.12 +
    1.13 +// Weave should always exist before before this file gets included.
    1.14 +let gSyncUtils = {
    1.15 +  get bundle() {
    1.16 +    delete this.bundle;
    1.17 +    return this.bundle = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties");
    1.18 +  },
    1.19 +
    1.20 +  get fxAccountsEnabled() {
    1.21 +    let service = Components.classes["@mozilla.org/weave/service;1"]
    1.22 +                            .getService(Components.interfaces.nsISupports)
    1.23 +                            .wrappedJSObject;
    1.24 +    return service.fxAccountsEnabled;
    1.25 +  },
    1.26 +
    1.27 +  // opens in a new window if we're in a modal prefwindow world, in a new tab otherwise
    1.28 +  _openLink: function (url) {
    1.29 +    let thisDocEl = document.documentElement,
    1.30 +        openerDocEl = window.opener && window.opener.document.documentElement;
    1.31 +    if (thisDocEl.id == "accountSetup" && window.opener &&
    1.32 +        openerDocEl.id == "BrowserPreferences" && !openerDocEl.instantApply)
    1.33 +      openUILinkIn(url, "window");
    1.34 +    else if (thisDocEl.id == "BrowserPreferences" && !thisDocEl.instantApply)
    1.35 +      openUILinkIn(url, "window");
    1.36 +    else if (document.documentElement.id == "change-dialog")
    1.37 +      Services.wm.getMostRecentWindow("navigator:browser")
    1.38 +              .openUILinkIn(url, "tab");
    1.39 +    else
    1.40 +      openUILinkIn(url, "tab");
    1.41 +  },
    1.42 +
    1.43 +  changeName: function changeName(input) {
    1.44 +    // Make sure to update to a modified name, e.g., empty-string -> default
    1.45 +    Weave.Service.clientsEngine.localName = input.value;
    1.46 +    input.value = Weave.Service.clientsEngine.localName;
    1.47 +  },
    1.48 +
    1.49 +  openChange: function openChange(type, duringSetup) {
    1.50 +    // Just re-show the dialog if it's already open
    1.51 +    let openedDialog = Services.wm.getMostRecentWindow("Sync:" + type);
    1.52 +    if (openedDialog != null) {
    1.53 +      openedDialog.focus();
    1.54 +      return;
    1.55 +    }
    1.56 +
    1.57 +    // Open up the change dialog
    1.58 +    let changeXUL = "chrome://browser/content/sync/genericChange.xul";
    1.59 +    let changeOpt = "centerscreen,chrome,resizable=no";
    1.60 +    Services.ww.activeWindow.openDialog(changeXUL, "", changeOpt,
    1.61 +                                        type, duringSetup);
    1.62 +  },
    1.63 +
    1.64 +  changePassword: function () {
    1.65 +    if (Weave.Utils.ensureMPUnlocked())
    1.66 +      this.openChange("ChangePassword");
    1.67 +  },
    1.68 +
    1.69 +  resetPassphrase: function (duringSetup) {
    1.70 +    if (Weave.Utils.ensureMPUnlocked())
    1.71 +      this.openChange("ResetPassphrase", duringSetup);
    1.72 +  },
    1.73 +
    1.74 +  updatePassphrase: function () {
    1.75 +    if (Weave.Utils.ensureMPUnlocked())
    1.76 +      this.openChange("UpdatePassphrase");
    1.77 +  },
    1.78 +
    1.79 +  resetPassword: function () {
    1.80 +    this._openLink(Weave.Service.pwResetURL);
    1.81 +  },
    1.82 +
    1.83 +  openToS: function () {
    1.84 +    let root = this.fxAccountsEnabled ? "fxa." : "";
    1.85 +    this._openLink(Weave.Svc.Prefs.get(root + "termsURL"));
    1.86 +  },
    1.87 +
    1.88 +  openPrivacyPolicy: function () {
    1.89 +    let root = this.fxAccountsEnabled ? "fxa." : "";
    1.90 +    this._openLink(Weave.Svc.Prefs.get(root + "privacyURL"));
    1.91 +  },
    1.92 +
    1.93 +  openMPInfoPage: function (event) {
    1.94 +    event.stopPropagation();
    1.95 +    let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
    1.96 +    this._openLink(baseURL + "sync-master-password");
    1.97 +  },
    1.98 +
    1.99 +  openFirstSyncProgressPage: function () {
   1.100 +    this._openLink("about:sync-progress");
   1.101 +  },
   1.102 +
   1.103 +  /**
   1.104 +   * Prepare an invisible iframe with the passphrase backup document.
   1.105 +   * Used by both the print and saving methods.
   1.106 +   *
   1.107 +   * @param elid : ID of the form element containing the passphrase.
   1.108 +   * @param callback : Function called once the iframe has loaded.
   1.109 +   */
   1.110 +  _preparePPiframe: function(elid, callback) {
   1.111 +    let pp = document.getElementById(elid).value;
   1.112 +
   1.113 +    // Create an invisible iframe whose contents we can print.
   1.114 +    let iframe = document.createElement("iframe");
   1.115 +    iframe.setAttribute("src", "chrome://browser/content/sync/key.xhtml");
   1.116 +    iframe.collapsed = true;
   1.117 +    document.documentElement.appendChild(iframe);
   1.118 +    iframe.contentWindow.addEventListener("load", function() {
   1.119 +      iframe.contentWindow.removeEventListener("load", arguments.callee, false);
   1.120 +
   1.121 +      // Insert the Sync Key into the page.
   1.122 +      let el = iframe.contentDocument.getElementById("synckey");
   1.123 +      el.firstChild.nodeValue = pp;
   1.124 +
   1.125 +      // Insert the TOS and Privacy Policy URLs into the page.
   1.126 +      let termsURL = Weave.Svc.Prefs.get("termsURL");
   1.127 +      el = iframe.contentDocument.getElementById("tosLink");
   1.128 +      el.setAttribute("href", termsURL);
   1.129 +      el.firstChild.nodeValue = termsURL;
   1.130 +
   1.131 +      let privacyURL = Weave.Svc.Prefs.get("privacyURL");
   1.132 +      el = iframe.contentDocument.getElementById("ppLink");
   1.133 +      el.setAttribute("href", privacyURL);
   1.134 +      el.firstChild.nodeValue = privacyURL;
   1.135 +
   1.136 +      callback(iframe);
   1.137 +    }, false);
   1.138 +  },
   1.139 +
   1.140 +  /**
   1.141 +   * Print passphrase backup document.
   1.142 +   * 
   1.143 +   * @param elid : ID of the form element containing the passphrase.
   1.144 +   */
   1.145 +  passphrasePrint: function(elid) {
   1.146 +    this._preparePPiframe(elid, function(iframe) {
   1.147 +      let webBrowserPrint = iframe.contentWindow
   1.148 +                                  .QueryInterface(Ci.nsIInterfaceRequestor)
   1.149 +                                  .getInterface(Ci.nsIWebBrowserPrint);
   1.150 +      let printSettings = PrintUtils.getPrintSettings();
   1.151 +
   1.152 +      // Display no header/footer decoration except for the date.
   1.153 +      printSettings.headerStrLeft
   1.154 +        = printSettings.headerStrCenter
   1.155 +        = printSettings.headerStrRight
   1.156 +        = printSettings.footerStrLeft
   1.157 +        = printSettings.footerStrCenter = "";
   1.158 +      printSettings.footerStrRight = "&D";
   1.159 +
   1.160 +      try {
   1.161 +        webBrowserPrint.print(printSettings, null);
   1.162 +      } catch (ex) {
   1.163 +        // print()'s return codes are expressed as exceptions. Ignore.
   1.164 +      }
   1.165 +    });
   1.166 +  },
   1.167 +
   1.168 +  /**
   1.169 +   * Save passphrase backup document to disk as HTML file.
   1.170 +   * 
   1.171 +   * @param elid : ID of the form element containing the passphrase.
   1.172 +   */
   1.173 +  passphraseSave: function(elid) {
   1.174 +    let dialogTitle = this.bundle.GetStringFromName("save.recoverykey.title");
   1.175 +    let defaultSaveName = this.bundle.GetStringFromName("save.recoverykey.defaultfilename");
   1.176 +    this._preparePPiframe(elid, function(iframe) {
   1.177 +      let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
   1.178 +      let fpCallback = function fpCallback_done(aResult) {
   1.179 +        if (aResult == Ci.nsIFilePicker.returnOK ||
   1.180 +            aResult == Ci.nsIFilePicker.returnReplace) {
   1.181 +          let stream = Cc["@mozilla.org/network/file-output-stream;1"].
   1.182 +                       createInstance(Ci.nsIFileOutputStream);
   1.183 +          stream.init(fp.file, -1, PERMISSIONS_RWUSR, 0);
   1.184 +
   1.185 +          let serializer = new XMLSerializer();
   1.186 +          let output = serializer.serializeToString(iframe.contentDocument);
   1.187 +          output = output.replace(/<!DOCTYPE (.|\n)*?]>/,
   1.188 +            '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' +
   1.189 +            '"DTD/xhtml1-strict.dtd">');
   1.190 +          output = Weave.Utils.encodeUTF8(output);
   1.191 +          stream.write(output, output.length);
   1.192 +        }
   1.193 +      };
   1.194 +
   1.195 +      fp.init(window, dialogTitle, Ci.nsIFilePicker.modeSave);
   1.196 +      fp.appendFilters(Ci.nsIFilePicker.filterHTML);
   1.197 +      fp.defaultString = defaultSaveName;
   1.198 +      fp.open(fpCallback);
   1.199 +      return false;
   1.200 +    });
   1.201 +  },
   1.202 +
   1.203 +  /**
   1.204 +   * validatePassword
   1.205 +   *
   1.206 +   * @param el1 : the first textbox element in the form
   1.207 +   * @param el2 : the second textbox element, if omitted it's an update form
   1.208 +   * 
   1.209 +   * returns [valid, errorString]
   1.210 +   */
   1.211 +  validatePassword: function (el1, el2) {
   1.212 +    let valid = false;
   1.213 +    let val1 = el1.value;
   1.214 +    let val2 = el2 ? el2.value : "";
   1.215 +    let error = "";
   1.216 +
   1.217 +    if (!el2)
   1.218 +      valid = val1.length >= Weave.MIN_PASS_LENGTH;
   1.219 +    else if (val1 && val1 == Weave.Service.identity.username)
   1.220 +      error = "change.password.pwSameAsUsername";
   1.221 +    else if (val1 && val1 == Weave.Service.identity.account)
   1.222 +      error = "change.password.pwSameAsEmail";
   1.223 +    else if (val1 && val1 == Weave.Service.identity.basicPassword)
   1.224 +      error = "change.password.pwSameAsPassword";
   1.225 +    else if (val1 && val2) {
   1.226 +      if (val1 == val2 && val1.length >= Weave.MIN_PASS_LENGTH)
   1.227 +        valid = true;
   1.228 +      else if (val1.length < Weave.MIN_PASS_LENGTH)
   1.229 +        error = "change.password.tooShort";
   1.230 +      else if (val1 != val2)
   1.231 +        error = "change.password.mismatch";
   1.232 +    }
   1.233 +    let errorString = error ? Weave.Utils.getErrorString(error) : "";
   1.234 +    return [valid, errorString];
   1.235 +  }
   1.236 +};

mercurial