Bug 1383663 part 2 - Remove fx-desktop-v1 client capabilities from aboutaccounts.js. r?markh, rfkelly draft
authorEdouard Oger <eoger@fastmail.com>
Wed, 30 Aug 2017 14:32:38 -0400
changeset 665956 2c3efe762d7a46dae42dd0aef4613bb16054dfc6
parent 665955 e0510ea461479f03747f7ec89144cc6171b57ec4
child 665957 c0fc5f79f32cdd855c9c5f5739f75e5662c1ffc8
push id80234
push userbmo:eoger@fastmail.com
push dateSat, 16 Sep 2017 19:17:57 +0000
reviewersmarkh, rfkelly
bugs1383663
milestone57.0a1
Bug 1383663 part 2 - Remove fx-desktop-v1 client capabilities from aboutaccounts.js. r?markh, rfkelly MozReview-Commit-ID: Ksh1AgAeski
browser/base/content/aboutaccounts/aboutaccounts.js
browser/base/content/test/sync/accounts_testRemoteCommands.html
browser/base/content/test/sync/browser.ini
browser/base/content/test/sync/browser_aboutAccounts.js
--- a/browser/base/content/aboutaccounts/aboutaccounts.js
+++ b/browser/base/content/aboutaccounts/aboutaccounts.js
@@ -11,88 +11,27 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/FxAccounts.jsm");
 
 var fxAccountsCommon = {};
 Cu.import("resource://gre/modules/FxAccountsCommon.js", fxAccountsCommon);
 
 // for master-password utilities
 Cu.import("resource://services-sync/util.js");
 
-const PREF_LAST_FXA_USER = "identity.fxaccounts.lastSignedInUserHash";
-
 const ACTION_URL_PARAM = "action";
 
 const OBSERVER_TOPICS = [
   fxAccountsCommon.ONVERIFIED_NOTIFICATION,
   fxAccountsCommon.ONLOGOUT_NOTIFICATION,
 ];
 
 function log(msg) {
   // dump("FXA: " + msg + "\n");
 }
 
-function getPreviousAccountNameHash() {
-  try {
-    return Services.prefs.getStringPref(PREF_LAST_FXA_USER);
-  } catch (_) {
-    return "";
-  }
-}
-
-function setPreviousAccountNameHash(acctName) {
-  Services.prefs.setStringPref(PREF_LAST_FXA_USER, sha256(acctName));
-}
-
-function needRelinkWarning(acctName) {
-  let prevAcctHash = getPreviousAccountNameHash();
-  return prevAcctHash && prevAcctHash != sha256(acctName);
-}
-
-// Given a string, returns the SHA265 hash in base64
-function sha256(str) {
-  let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
-                    .createInstance(Ci.nsIScriptableUnicodeConverter);
-  converter.charset = "UTF-8";
-  // Data is an array of bytes.
-  let data = converter.convertToByteArray(str, {});
-  let hasher = Cc["@mozilla.org/security/hash;1"]
-                 .createInstance(Ci.nsICryptoHash);
-  hasher.init(hasher.SHA256);
-  hasher.update(data, data.length);
-
-  return hasher.finish(true);
-}
-
-function promptForRelink(acctName) {
-  let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties");
-  let continueLabel = sb.GetStringFromName("continue.label");
-  let title = sb.GetStringFromName("relinkVerify.title");
-  let description = sb.formatStringFromName("relinkVerify.description",
-                                            [acctName], 1);
-  let body = sb.GetStringFromName("relinkVerify.heading") +
-             "\n\n" + description;
-  let ps = Services.prompt;
-  let buttonFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING) +
-                    (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL) +
-                    ps.BUTTON_POS_1_DEFAULT;
-  let pressed = Services.prompt.confirmEx(window, title, body, buttonFlags,
-                                     continueLabel, null, null, null,
-                                     {});
-  return pressed == 0; // 0 is the "continue" button
-}
-
-// If the last fxa account used for sync isn't this account, we display
-// a modal dialog checking they really really want to do this...
-// (This is sync-specific, so ideally would be in sync's identity module,
-// but it's a little more seamless to do here, and sync is currently the
-// only fxa consumer, so...
-function shouldAllowRelink(acctName) {
-  return !needRelinkWarning(acctName) || promptForRelink(acctName);
-}
-
 function updateDisplayedEmail(user) {
   let emailDiv = document.getElementById("email");
   if (emailDiv && user) {
     emailDiv.textContent = user.email;
   }
 }
 
 var wrapper = {
@@ -107,17 +46,16 @@ var wrapper = {
 
     let iframe = document.getElementById("remote");
     this.iframe = iframe;
     let docShell = this.iframe.frameLoader.docShell;
     docShell.QueryInterface(Ci.nsIWebProgress);
     docShell.addProgressListener(this.iframeListener,
                                  Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT |
                                  Ci.nsIWebProgress.NOTIFY_LOCATION);
-    iframe.addEventListener("load", this);
 
     // Ideally we'd just merge urlParams with new URL(url).searchParams, but our
     // URLSearchParams implementation doesn't support iteration (bug 1085284).
     let urlParamStr = urlParams.toString();
     if (urlParamStr) {
       url += (url.includes("?") ? "&" : "?") + urlParamStr;
     }
     this.url = url;
@@ -163,143 +101,17 @@ var wrapper = {
     },
 
     onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
       if (aRequest && aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) {
         aRequest.cancel(Components.results.NS_BINDING_ABORTED);
         setErrorPage("networkError");
       }
     },
-  },
-
-  handleEvent(evt) {
-    switch (evt.type) {
-      case "load":
-        this.iframe.contentWindow.addEventListener("FirefoxAccountsCommand", this);
-        this.iframe.removeEventListener("load", this);
-        break;
-      case "FirefoxAccountsCommand":
-        this.handleRemoteCommand(evt);
-        break;
-    }
-  },
-
-  /**
-   * onLogin handler receives user credentials from the jelly after a
-   * sucessful login and stores it in the fxaccounts service
-   *
-   * @param accountData the user's account data and credentials
-   */
-  onLogin(accountData) {
-    log("Received: 'login'. Data:" + JSON.stringify(accountData));
-
-    // We don't act on customizeSync anymore, it used to open a dialog inside
-    // the browser to selecte the engines to sync but we do it on the web now.
-    delete accountData.customizeSync;
-    // sessionTokenContext is erroneously sent by the content server.
-    // https://github.com/mozilla/fxa-content-server/issues/2766
-    // To avoid having the FxA storage manager not knowing what to do with
-    // it we delete it here.
-    delete accountData.sessionTokenContext;
-
-    // We need to confirm a relink - see shouldAllowRelink for more
-    let newAccountEmail = accountData.email;
-    // The hosted code may have already checked for the relink situation
-    // by sending the can_link_account command. If it did, then
-    // it will indicate we don't need to ask twice.
-    if (!accountData.verifiedCanLinkAccount && !shouldAllowRelink(newAccountEmail)) {
-      // we need to tell the page we successfully received the message, but
-      // then bail without telling fxAccounts
-      this.injectData("message", { status: "login" });
-      // after a successful login we return to preferences
-      openPrefs();
-      return;
-    }
-    delete accountData.verifiedCanLinkAccount;
-
-    // Remember who it was so we can log out next time.
-    setPreviousAccountNameHash(newAccountEmail);
-
-    // 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(() => {
-      updateDisplayedEmail(accountData);
-      return fxAccounts.setSignedInUser(accountData);
-    }).then(() => {
-      // If the user data is verified, we want it to immediately look like
-      // they are signed in without waiting for messages to bounce around.
-      if (accountData.verified) {
-        openPrefs();
-      }
-      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 })
-    );
-  },
-
-  onCanLinkAccount(accountData) {
-    // We need to confirm a relink - see shouldAllowRelink for more
-    let ok = shouldAllowRelink(accountData.email);
-    this.injectData("message", { status: "can_link_account", data: { ok } });
-  },
-
-  /**
-   * onSignOut handler erases the current user's session from the fxaccounts service
-   */
-  onSignOut() {
-    log("Received: 'sign_out'.");
-
-    fxAccounts.signOut().then(
-      () => this.injectData("message", { status: "sign_out" }),
-      (err) => this.injectData("message", { status: "error", error: err })
-    );
-  },
-
-  handleRemoteCommand(evt) {
-    log("command: " + evt.detail.command);
-    let data = evt.detail.data;
-
-    switch (evt.detail.command) {
-      case "login":
-        this.onLogin(data);
-        break;
-      case "can_link_account":
-        this.onCanLinkAccount(data);
-        break;
-      case "sign_out":
-        this.onSignOut(data);
-        break;
-      default:
-        log("Unexpected remote command received: " + evt.detail.command + ". Ignoring command.");
-        break;
-    }
-  },
-
-  injectData(type, content) {
-    return fxAccounts.promiseAccountsSignUpURI().then(authUrl => {
-      let data = {
-        type,
-        content
-      };
-      this.iframe.contentWindow.postMessage(data, authUrl);
-    })
-    .catch(e => {
-      console.log("Failed to inject data", e);
-      setErrorPage("configError");
-    });
-  },
+  }
 };
 
 
 // Button onclick handlers
 
 function getStarted() {
   show("remote");
 }
deleted file mode 100644
--- a/browser/base/content/test/sync/accounts_testRemoteCommands.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<html>
-  <head>
-    <meta charset="utf-8">
-
-<script type="text/javascript">
-
-function init() {
-  window.addEventListener("message", function process(e) { doTest(e) });
-  // unless we relinquish the eventloop,
-  // tests will run before the chrome event handlers are ready
-  setTimeout(doTest, 0);
-}
-
-function checkStatusValue(payload, expectedValue) {
-  return payload.status == expectedValue;
-}
-
-let tests = [
-{
-  info: "Check account log in",
-  event: "login",
-  data: {
-    email: "foo@example.com",
-    uid: "1234@lcip.org",
-    assertion: "foobar",
-    sessionToken: "dead",
-    kA: "beef",
-    kB: "cafe",
-    verified: true
-  },
-  payloadType: "message",
-  validateResponse(payload) {
-    return checkStatusValue(payload, "login");
-  },
-},
-];
-
-let currentTest = -1;
-function doTest(evt) {
-  if (evt) {
-    if (currentTest < 0 || !evt.data.content)
-      return; // not yet testing
-
-    let test = tests[currentTest];
-    if (evt.data.type != test.payloadType)
-      return; // skip unrequested events
-
-    let error = JSON.stringify(evt.data.content);
-    let pass = false;
-    try {
-      pass = test.validateResponse(evt.data.content)
-    } catch (e) {}
-    reportResult(test.info, pass, error);
-  }
-  // start the next test if there are any left
-  if (tests[++currentTest])
-    sendToBrowser(tests[currentTest].event, tests[currentTest].data);
-  else
-    reportFinished();
-}
-
-function reportResult(info, pass, error) {
-  let data = {type: "testResult", info, pass, error};
-  let event = new CustomEvent("FirefoxAccountsTestResponse", {detail: {data}, bubbles: true});
-  document.dispatchEvent(event);
-}
-
-function reportFinished(cmd) {
-  let data = {type: "testsComplete", count: tests.length};
-  let event = new CustomEvent("FirefoxAccountsTestResponse", {detail: {data}, bubbles: true});
-  document.dispatchEvent(event);
-}
-
-function sendToBrowser(type, data) {
-  let event = new CustomEvent("FirefoxAccountsCommand", {detail: {command: type, data}, bubbles: true});
-  document.dispatchEvent(event);
-}
-
-</script>
-  </head>
-  <body onload="init()">
-  </body>
-</html>
--- a/browser/base/content/test/sync/browser.ini
+++ b/browser/base/content/test/sync/browser.ini
@@ -8,9 +8,8 @@ support-files =
 [browser_fxa_web_channel.js]
 support-files=
   browser_fxa_web_channel.html
 [browser_fxa_badge.js]
 [browser_aboutAccounts.js]
 skip-if = os == "linux" # Bug 958026
 support-files =
   content_aboutAccounts.js
-  accounts_testRemoteCommands.html
--- a/browser/base/content/test/sync/browser_aboutAccounts.js
+++ b/browser/base/content/test/sync/browser_aboutAccounts.js
@@ -22,54 +22,16 @@ registerCleanupFunction(function() {
   // Ensure we don't pollute prefs for next tests.
   for (let name of changedPrefs) {
     Services.prefs.clearUserPref(name);
   }
 });
 
 var gTests = [
 {
-  desc: "Test the remote commands",
-  async teardown() {
-    gBrowser.removeCurrentTab();
-    await signOut();
-  },
-  async run() {
-    setPref("identity.fxaccounts.remote.signup.uri",
-            "https://example.com/browser/browser/base/content/test/sync/accounts_testRemoteCommands.html");
-    let tab = await promiseNewTabLoadEvent("about:accounts");
-    let mm = tab.linkedBrowser.messageManager;
-
-    let deferred = Promise.defer();
-
-    // We'll get a message when openPrefs() is called, which this test should
-    // arrange.
-    let promisePrefsOpened = promiseOneMessage(tab, "test:openPrefsCalled");
-    let results = 0;
-    try {
-      mm.addMessageListener("test:response", function responseHandler(msg) {
-        let data = msg.data.data;
-        if (data.type == "testResult") {
-          ok(data.pass, data.info);
-          results++;
-        } else if (data.type == "testsComplete") {
-          is(results, data.count, "Checking number of results received matches the number of tests that should have run");
-          mm.removeMessageListener("test:response", responseHandler);
-          deferred.resolve();
-        }
-      });
-    } catch (e) {
-      ok(false, "Failed to get all commands");
-      deferred.reject();
-    }
-    await deferred.promise;
-    await promisePrefsOpened;
-  }
-},
-{
   desc: "Test action=signin - no user logged in",
   teardown: () => gBrowser.removeCurrentTab(),
   async run() {
     // When this loads with no user logged-in, we expect the "normal" URL
     const expected_url = "https://example.com/?is_sign_in";
     setPref("identity.fxaccounts.remote.signin.uri", expected_url);
     let [tab, url] = await promiseNewTabWithIframeLoadEvent("about:accounts?action=signin");
     is(url, expected_url, "action=signin got the expected URL");