utils.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. // Equivalent to 0o600 permissions; used for saved Sync Recovery Key.
  5. // This constant can be replaced when the equivalent values are available to
  6. // chrome JS; see Bug 433295 and Bug 757351.
  7. const PERMISSIONS_RWUSR = 0x180;
  8. // Weave should always exist before before this file gets included.
  9. var gSyncUtils = {
  10. get bundle() {
  11. delete this.bundle;
  12. return this.bundle = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties");
  13. },
  14. // opens in a new window if we're in a modal prefwindow world, in a new tab otherwise
  15. _openLink: function(url) {
  16. let thisDocEl = document.documentElement,
  17. openerDocEl = window.opener && window.opener.document.documentElement;
  18. if (thisDocEl.id == "accountSetup" && window.opener &&
  19. openerDocEl.id == "BrowserPreferences" && !openerDocEl.instantApply)
  20. openUILinkIn(url, "window");
  21. else if (thisDocEl.id == "BrowserPreferences" && !thisDocEl.instantApply)
  22. openUILinkIn(url, "window");
  23. else if (document.documentElement.id == "change-dialog")
  24. Services.wm.getMostRecentWindow("navigator:browser")
  25. .openUILinkIn(url, "tab");
  26. else
  27. openUILinkIn(url, "tab");
  28. },
  29. changeName: function(input) {
  30. // Make sure to update to a modified name, e.g., empty-string -> default
  31. Weave.Service.clientsEngine.localName = input.value;
  32. input.value = Weave.Service.clientsEngine.localName;
  33. },
  34. openChange: function(type, duringSetup) {
  35. // Just re-show the dialog if it's already open
  36. let openedDialog = Services.wm.getMostRecentWindow("Sync:" + type);
  37. if (openedDialog != null) {
  38. openedDialog.focus();
  39. return;
  40. }
  41. // Open up the change dialog
  42. let changeXUL = "chrome://browser/content/sync/genericChange.xul";
  43. let changeOpt = "centerscreen,chrome,resizable=no";
  44. Services.ww.activeWindow.openDialog(changeXUL, "", changeOpt,
  45. type, duringSetup);
  46. },
  47. changePassword: function() {
  48. if (Weave.Utils.ensureMPUnlocked())
  49. this.openChange("ChangePassword");
  50. },
  51. resetPassphrase: function(duringSetup) {
  52. if (Weave.Utils.ensureMPUnlocked())
  53. this.openChange("ResetPassphrase", duringSetup);
  54. },
  55. updatePassphrase: function() {
  56. if (Weave.Utils.ensureMPUnlocked())
  57. this.openChange("UpdatePassphrase");
  58. },
  59. resetPassword: function() {
  60. this._openLink(Weave.Service.pwResetURL);
  61. },
  62. openToS: function() {
  63. this._openLink(Weave.Svc.Prefs.get("termsURL"));
  64. },
  65. openPrivacyPolicy: function() {
  66. this._openLink(Weave.Svc.Prefs.get("privacyURL"));
  67. },
  68. openFirstSyncProgressPage: function() {
  69. this._openLink("about:sync-progress");
  70. },
  71. /**
  72. * Prepare an invisible iframe with the passphrase backup document.
  73. * Used by both the print and saving methods.
  74. *
  75. * @param elid : ID of the form element containing the passphrase.
  76. * @param callback : Function called once the iframe has loaded.
  77. */
  78. _preparePPiframe: function(elid, callback) {
  79. let pp = document.getElementById(elid).value;
  80. // Create an invisible iframe whose contents we can print.
  81. let iframe = document.createElement("iframe");
  82. iframe.setAttribute("src", "chrome://browser/content/sync/key.xhtml");
  83. iframe.collapsed = true;
  84. document.documentElement.appendChild(iframe);
  85. iframe.contentWindow.addEventListener("load", function() {
  86. iframe.contentWindow.removeEventListener("load", arguments.callee, false);
  87. // Insert the Sync Key into the page.
  88. let el = iframe.contentDocument.getElementById("synckey");
  89. el.firstChild.nodeValue = pp;
  90. // Insert the TOS and Privacy Policy URLs into the page.
  91. let termsURL = Weave.Svc.Prefs.get("termsURL");
  92. el = iframe.contentDocument.getElementById("tosLink");
  93. el.setAttribute("href", termsURL);
  94. el.firstChild.nodeValue = termsURL;
  95. let privacyURL = Weave.Svc.Prefs.get("privacyURL");
  96. el = iframe.contentDocument.getElementById("ppLink");
  97. el.setAttribute("href", privacyURL);
  98. el.firstChild.nodeValue = privacyURL;
  99. callback(iframe);
  100. }, false);
  101. },
  102. /**
  103. * Print passphrase backup document.
  104. *
  105. * @param elid : ID of the form element containing the passphrase.
  106. */
  107. passphrasePrint: function(elid) {
  108. this._preparePPiframe(elid, function(iframe) {
  109. let webBrowserPrint = iframe.contentWindow
  110. .QueryInterface(Ci.nsIInterfaceRequestor)
  111. .getInterface(Ci.nsIWebBrowserPrint);
  112. let printSettings = PrintUtils.getPrintSettings();
  113. // Display no header/footer decoration except for the date.
  114. printSettings.headerStrLeft
  115. = printSettings.headerStrCenter
  116. = printSettings.headerStrRight
  117. = printSettings.footerStrLeft
  118. = printSettings.footerStrCenter = "";
  119. printSettings.footerStrRight = "&D";
  120. try {
  121. webBrowserPrint.print(printSettings, null);
  122. } catch (ex) {
  123. // print()'s return codes are expressed as exceptions. Ignore.
  124. }
  125. });
  126. },
  127. /**
  128. * Save passphrase backup document to disk as HTML file.
  129. *
  130. * @param elid : ID of the form element containing the passphrase.
  131. */
  132. passphraseSave: function(elid) {
  133. let dialogTitle = this.bundle.GetStringFromName("save.recoverykey.title");
  134. let defaultSaveName = this.bundle.GetStringFromName("save.recoverykey.defaultfilename");
  135. this._preparePPiframe(elid, function(iframe) {
  136. let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
  137. let fpCallback = function fpCallback_done(aResult) {
  138. if (aResult == Ci.nsIFilePicker.returnOK ||
  139. aResult == Ci.nsIFilePicker.returnReplace) {
  140. let stream = Cc["@mozilla.org/network/file-output-stream;1"].
  141. createInstance(Ci.nsIFileOutputStream);
  142. stream.init(fp.file, -1, PERMISSIONS_RWUSR, 0);
  143. let serializer = new XMLSerializer();
  144. let output = serializer.serializeToString(iframe.contentDocument);
  145. output = output.replace(/<!DOCTYPE (.|\n)*?]>/,
  146. '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' +
  147. '"DTD/xhtml1-strict.dtd">');
  148. output = Weave.Utils.encodeUTF8(output);
  149. stream.write(output, output.length);
  150. }
  151. };
  152. fp.init(window, dialogTitle, Ci.nsIFilePicker.modeSave);
  153. fp.appendFilters(Ci.nsIFilePicker.filterHTML);
  154. fp.defaultString = defaultSaveName;
  155. fp.open(fpCallback);
  156. return false;
  157. });
  158. },
  159. /**
  160. * validatePassword
  161. *
  162. * @param el1 : the first textbox element in the form
  163. * @param el2 : the second textbox element, if omitted it's an update form
  164. *
  165. * returns [valid, errorString]
  166. */
  167. validatePassword: function(el1, el2) {
  168. let valid = false;
  169. let val1 = el1.value;
  170. let val2 = el2 ? el2.value : "";
  171. let error = "";
  172. if (!el2)
  173. valid = val1.length >= Weave.MIN_PASS_LENGTH;
  174. else if (val1 && val1 == Weave.Service.identity.username)
  175. error = "change.password.pwSameAsUsername";
  176. else if (val1 && val1 == Weave.Service.identity.account)
  177. error = "change.password.pwSameAsEmail";
  178. else if (val1 && val1 == Weave.Service.identity.basicPassword)
  179. error = "change.password.pwSameAsPassword";
  180. else if (val1 && val2) {
  181. if (val1 == val2 && val1.length >= Weave.MIN_PASS_LENGTH)
  182. valid = true;
  183. else if (val1.length < Weave.MIN_PASS_LENGTH)
  184. error = "change.password.tooShort";
  185. else if (val1 != val2)
  186. error = "change.password.mismatch";
  187. }
  188. let errorString = error ? Weave.Utils.getErrorString(error) : "";
  189. return [valid, errorString];
  190. }
  191. };