Bug 1309030 - Remove DOM/identity and related code. r?ehsan draft
authorMichelangelo De Simone <mdesimone@mozilla.com>
Mon, 10 Oct 2016 13:55:16 -0700
changeset 423915 6ddb7628a7223c643ceaed1956b49ff4e23007f0
parent 423604 7ae377917236b7e6111146aa9fb4c073c0efc7f4
child 533554 e349151d17e21f2fa1c4b06b7ff767bffa28e989
push id32023
push usermdesimone@mozilla.com
push dateTue, 11 Oct 2016 21:36:43 +0000
reviewersehsan
bugs1309030
milestone52.0a1
Bug 1309030 - Remove DOM/identity and related code. r?ehsan MozReview-Commit-ID: 2v2ZCSoX4Mz
b2g/app/b2g.js
dom/identity/DOMIdentity.jsm
dom/identity/Identity.manifest
dom/identity/moz.build
dom/identity/nsDOMIdentity.js
dom/identity/nsIDService.js
dom/identity/tests/mochitest/chrome.ini
dom/identity/tests/mochitest/file_browserid_rp_noOnlogin.html
dom/identity/tests/mochitest/file_browserid_rp_ok.html
dom/identity/tests/mochitest/file_declareAudience.html
dom/identity/tests/mochitest/file_fxa_rp_noOnlogin.html
dom/identity/tests/mochitest/file_fxa_rp_noOnlogout.html
dom/identity/tests/mochitest/file_fxa_rp_noOnready.html
dom/identity/tests/mochitest/file_fxa_rp_ok.html
dom/identity/tests/mochitest/file_syntheticEvents.html
dom/identity/tests/mochitest/test_declareAudience.html
dom/identity/tests/mochitest/test_rpHasValidCallbacks.html
dom/identity/tests/mochitest/test_syntheticEvents.html
dom/moz.build
dom/webidl/Identity.webidl
dom/webidl/moz.build
services/fxaccounts/tests/mochitest/test_invalidEmailCase.html
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -786,19 +786,16 @@ pref("memory.free_dirty_pages", true);
 pref("memory.system_memory_reporter", true);
 
 // Don't dump memory reports on OOM, by default.
 pref("memory.dump_reports_on_oom", false);
 
 pref("layout.framevisibility.numscrollportwidths", 1);
 pref("layout.framevisibility.numscrollportheights", 1);
 
-// Enable native identity (persona/browserid)
-pref("dom.identity.enabled", true);
-
 // Wait up to this much milliseconds when orientation changed
 pref("layers.orientation.sync.timeout", 1000);
 
 // Animate the orientation change
 pref("b2g.orientation.animate", true);
 
 // Don't discard WebGL contexts for foreground apps on memory
 // pressure.
@@ -957,17 +954,17 @@ pref("layout.accessiblecaret.enabled", t
 pref("layout.accessiblecaret.bar.enabled", true);
 
 // Hide the caret in cursor mode after 3 seconds.
 pref("layout.accessiblecaret.timeout_ms", 3000);
 
 // Hide carets and text selection dialog during scrolling.
 pref("layout.accessiblecaret.always_show_when_scrolling", false);
 
-// Enable sync and mozId with Firefox Accounts.
+// Enable sync with Firefox Accounts.
 pref("services.sync.fxaccounts.enabled", true);
 pref("identity.fxaccounts.enabled", true);
 
 pref("identity.fxaccounts.remote.oauth.uri", "https://oauth.accounts.firefox.com/v1");
 pref("identity.fxaccounts.remote.profile.uri", "https://profile.accounts.firefox.com/v1");
 
 // Disable Firefox Accounts device registration until bug 1238895 is fixed.
 pref("identity.fxaccounts.skipDeviceRegistration", true);
deleted file mode 100644
--- a/dom/identity/DOMIdentity.jsm
+++ /dev/null
@@ -1,478 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc,
-       interfaces: Ci,
-       utils: Cu,
-       results: Cr} = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const PREF_FXA_ENABLED = "identity.fxaccounts.enabled";
-const FXA_PERMISSION = "firefox-accounts";
-
-// This is the parent process corresponding to nsDOMIdentity.
-this.EXPORTED_SYMBOLS = ["DOMIdentity"];
-
-XPCOMUtils.defineLazyModuleGetter(this, "objectCopy",
-                                  "resource://gre/modules/identity/IdentityUtils.jsm");
-
-/* jshint ignore:start */
-XPCOMUtils.defineLazyModuleGetter(this, "IdentityService",
-#ifdef MOZ_B2G_VERSION
-                                  "resource://gre/modules/identity/MinimalIdentity.jsm");
-#else
-                                  "resource://gre/modules/identity/Identity.jsm");
-#endif
-/* jshint ignore:end */
-
-XPCOMUtils.defineLazyModuleGetter(this, "FirefoxAccounts",
-                                  "resource://gre/modules/identity/FirefoxAccounts.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "makeMessageObject",
-                                  "resource://gre/modules/identity/IdentityUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this,
-                                  "Logger",
-                                  "resource://gre/modules/identity/LogUtils.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
-                                   "@mozilla.org/parentprocessmessagemanager;1",
-                                   "nsIMessageListenerManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "permissionManager",
-                                   "@mozilla.org/permissionmanager;1",
-                                   "nsIPermissionManager");
-
-function log(...aMessageArgs) {
-  Logger.log.apply(Logger, ["DOMIdentity"].concat(aMessageArgs));
-}
-
-function IDDOMMessage(aOptions) {
-  objectCopy(aOptions, this);
-}
-
-function _sendAsyncMessage(identifier, message) {
-  if (this._mm) {
-    try {
-      this._mm.sendAsyncMessage(identifier, message);
-    } catch(err) {
-      // We may receive a NS_ERROR_NOT_INITIALIZED if the target window has
-      // been closed.  This can legitimately happen if an app has been killed
-      // while we are in the midst of a sign-in flow.
-      if (err.result == Cr.NS_ERROR_NOT_INITIALIZED) {
-        log("Cannot sendAsyncMessage because the recipient frame has closed");
-        return;
-      }
-      log("ERROR: sendAsyncMessage: " + err);
-    }
-  }
-};
-
-function IDPProvisioningContext(aID, aOrigin, aTargetMM) {
-  this._id = aID;
-  this._origin = aOrigin;
-  this._mm = aTargetMM;
-}
-
-IDPProvisioningContext.prototype = {
-  get id() { return this._id; },
-  get origin() { return this._origin; },
-
-  sendAsyncMessage: _sendAsyncMessage,
-
-  doBeginProvisioningCallback: function IDPPC_doBeginProvCB(aID, aCertDuration) {
-    let message = new IDDOMMessage({id: this.id});
-    message.identity = aID;
-    message.certDuration = aCertDuration;
-    this.sendAsyncMessage("Identity:IDP:CallBeginProvisioningCallback",
-                          message);
-  },
-
-  doGenKeyPairCallback: function IDPPC_doGenKeyPairCallback(aPublicKey) {
-    log("doGenKeyPairCallback");
-    let message = new IDDOMMessage({id: this.id});
-    message.publicKey = aPublicKey;
-    this.sendAsyncMessage("Identity:IDP:CallGenKeyPairCallback", message);
-  },
-
-  doError: function(msg) {
-    log("Provisioning ERROR: " + msg);
-  }
-};
-
-function IDPAuthenticationContext(aID, aOrigin, aTargetMM) {
-  this._id = aID;
-  this._origin = aOrigin;
-  this._mm = aTargetMM;
-}
-
-IDPAuthenticationContext.prototype = {
-  get id() { return this._id; },
-  get origin() { return this._origin; },
-
-  sendAsyncMessage: _sendAsyncMessage,
-
-  doBeginAuthenticationCallback: function IDPAC_doBeginAuthCB(aIdentity) {
-    let message = new IDDOMMessage({id: this.id});
-    message.identity = aIdentity;
-    this.sendAsyncMessage("Identity:IDP:CallBeginAuthenticationCallback",
-                          message);
-  },
-
-  doError: function IDPAC_doError(msg) {
-    log("Authentication ERROR: " + msg);
-  }
-};
-
-function RPWatchContext(aOptions, aTargetMM, aPrincipal) {
-  objectCopy(aOptions, this);
-
-  // id and origin are required
-  if (! (this.id && this.origin)) {
-    throw new Error("id and origin are required for RP watch context");
-  }
-
-  this.principal = aPrincipal;
-
-  // default for no loggedInUser is undefined, not null
-  this.loggedInUser = aOptions.loggedInUser;
-
-  // Maybe internal.  For hosted b2g identity shim.
-  this._internal = aOptions._internal;
-
-  this._mm = aTargetMM;
-}
-
-RPWatchContext.prototype = {
-  sendAsyncMessage: _sendAsyncMessage,
-
-  doLogin: function RPWatchContext_onlogin(aAssertion, aMaybeInternalParams) {
-    log("doLogin: " + this.id);
-    let message = new IDDOMMessage({id: this.id, assertion: aAssertion});
-    if (aMaybeInternalParams) {
-      message._internalParams = aMaybeInternalParams;
-    }
-    this.sendAsyncMessage("Identity:RP:Watch:OnLogin", message);
-  },
-
-  doLogout: function RPWatchContext_onlogout() {
-    log("doLogout: " + this.id);
-    let message = new IDDOMMessage({id: this.id});
-    this.sendAsyncMessage("Identity:RP:Watch:OnLogout", message);
-  },
-
-  doReady: function RPWatchContext_onready() {
-    log("doReady: " + this.id);
-    let message = new IDDOMMessage({id: this.id});
-    this.sendAsyncMessage("Identity:RP:Watch:OnReady", message);
-  },
-
-  doCancel: function RPWatchContext_oncancel() {
-    log("doCancel: " + this.id);
-    let message = new IDDOMMessage({id: this.id});
-    this.sendAsyncMessage("Identity:RP:Watch:OnCancel", message);
-  },
-
-  doError: function RPWatchContext_onerror(aMessage) {
-    log("doError: " + this.id + ": " + JSON.stringify(aMessage));
-    let message = new IDDOMMessage({id: this.id, message: aMessage});
-    this.sendAsyncMessage("Identity:RP:Watch:OnError", message);
-  }
-};
-
-this.DOMIdentity = {
-  /*
-   * When relying parties (RPs) invoke the watch() method, they can request
-   * to use Firefox Accounts as their auth service or BrowserID (the default).
-   * For each RP, we create an RPWatchContext to store the parameters given to
-   * watch(), and to provide hooks to invoke the onlogin(), onlogout(), etc.
-   * callbacks held in the nsDOMIdentity state.
-   *
-   * The serviceContexts map associates the window ID of the RP with the
-   * context object.  The mmContexts map associates a message manager with a
-   * window ID.  We use the mmContexts map when child-process-shutdown is
-   * observed, and all we have is a message manager to identify the window in
-   * question.
-   */
-  _serviceContexts: new Map(),
-  _mmContexts: new Map(),
-
-  /*
-   * Mockable, for testing
-   */
-  _mockIdentityService: null,
-  get IdentityService() {
-    if (this._mockIdentityService) {
-      log("Using a mocked identity service");
-      return this._mockIdentityService;
-    }
-    return IdentityService;
-  },
-
-  /*
-   * Create a new RPWatchContext, and update the context maps.
-   */
-  newContext: function(message, targetMM, principal) {
-    let context = new RPWatchContext(message, targetMM, principal);
-    this._serviceContexts.set(message.id, context);
-    this._mmContexts.set(targetMM, message.id);
-    return context;
-  },
-
-  /*
-   * Get the identity service used for an RP.
-   *
-   * @object message
-   *         A message received from an RP.  Will include the id of the window
-   *         whence the message originated.
-   *
-   * Returns FirefoxAccounts or IdentityService
-   */
-  getService: function(message) {
-    if (!this._serviceContexts.has(message.id)) {
-      log("ERROR: getService called before newContext for " + message.id);
-      return null;
-    }
-
-    let context = this._serviceContexts.get(message.id);
-    if (context.wantIssuer == "firefox-accounts") {
-      if (Services.prefs.getPrefType(PREF_FXA_ENABLED) === Ci.nsIPrefBranch.PREF_BOOL
-          && Services.prefs.getBoolPref(PREF_FXA_ENABLED)) {
-        return FirefoxAccounts;
-      }
-      log("WARNING: Firefox Accounts is not enabled; Defaulting to BrowserID");
-    }
-    return this.IdentityService;
-  },
-
-  /*
-   * Get the RPWatchContext object for a given message manager.
-   */
-  getContextForMM: function(targetMM) {
-    return this._serviceContexts.get(this._mmContexts.get(targetMM));
-  },
-
-  hasContextForMM: function(targetMM) {
-    return this._mmContexts.has(targetMM);
-  },
-
-  /*
-   * Delete the RPWatchContext object for a given message manager.  Removes the
-   * mapping both from _serviceContexts and _mmContexts.
-   */
-  deleteContextForMM: function(targetMM) {
-    this._serviceContexts.delete(this._mmContexts.get(targetMM));
-    this._mmContexts.delete(targetMM);
-  },
-
-  hasPermission: function(aMessage) {
-    // We only check that the firefox accounts permission is present in the
-    // manifest.
-    if (aMessage.json && aMessage.json.wantIssuer == "firefox-accounts") {
-      if (!aMessage.principal) {
-        return false;
-      }
-
-      let permission =
-        permissionManager.testPermissionFromPrincipal(aMessage.principal,
-                                                      FXA_PERMISSION);
-      return permission != Ci.nsIPermissionManager.UNKNOWN_ACTION &&
-             permission != Ci.nsIPermissionManager.DENY_ACTION;
-    }
-    return true;
-  },
-
-  // nsIMessageListener
-  receiveMessage: function DOMIdentity_receiveMessage(aMessage) {
-    let msg = aMessage.json;
-
-    // Target is the frame message manager that called us and is
-    // used to send replies back to the proper window.
-    let targetMM = aMessage.target;
-
-    if (!this.hasPermission(aMessage)) {
-      throw new Error("PERMISSION_DENIED");
-    }
-
-    switch (aMessage.name) {
-      // RP
-      case "Identity:RP:Watch":
-        this._watch(msg, targetMM, aMessage.principal);
-        break;
-      case "Identity:RP:Unwatch":
-        this._unwatch(msg, targetMM);
-        break;
-      case "Identity:RP:Request":
-        this._request(msg);
-        break;
-      case "Identity:RP:Logout":
-        this._logout(msg);
-        break;
-      // IDP
-      case "Identity:IDP:BeginProvisioning":
-        this._beginProvisioning(msg, targetMM);
-        break;
-      case "Identity:IDP:GenKeyPair":
-        this._genKeyPair(msg);
-        break;
-      case "Identity:IDP:RegisterCertificate":
-        this._registerCertificate(msg);
-        break;
-      case "Identity:IDP:ProvisioningFailure":
-        this._provisioningFailure(msg);
-        break;
-      case "Identity:IDP:BeginAuthentication":
-        this._beginAuthentication(msg, targetMM);
-        break;
-      case "Identity:IDP:CompleteAuthentication":
-        this._completeAuthentication(msg);
-        break;
-      case "Identity:IDP:AuthenticationFailure":
-        this._authenticationFailure(msg);
-        break;
-      case "child-process-shutdown":
-        // we receive child-process-shutdown if the appliction crashes,
-        // including if it is crashed by the OS (killed for out-of-memory,
-        // for example)
-        this._childProcessShutdown(targetMM);
-        break;
-    }
-  },
-
-  // nsIObserver
-  observe: function DOMIdentity_observe(aSubject, aTopic, aData) {
-    switch (aTopic) {
-      case "xpcom-shutdown":
-        this._unsubscribeListeners();
-        Services.obs.removeObserver(this, "xpcom-shutdown");
-        Services.ww.unregisterNotification(this);
-        break;
-    }
-  },
-
-  messages: ["Identity:RP:Watch", "Identity:RP:Request", "Identity:RP:Logout",
-             "Identity:IDP:BeginProvisioning", "Identity:IDP:ProvisioningFailure",
-             "Identity:IDP:RegisterCertificate", "Identity:IDP:GenKeyPair",
-             "Identity:IDP:BeginAuthentication",
-             "Identity:IDP:CompleteAuthentication",
-             "Identity:IDP:AuthenticationFailure",
-             "Identity:RP:Unwatch",
-             "child-process-shutdown"],
-
-  // Private.
-  _init: function DOMIdentity__init() {
-    Services.ww.registerNotification(this);
-    Services.obs.addObserver(this, "xpcom-shutdown", false);
-    this._subscribeListeners();
-  },
-
-  _subscribeListeners: function DOMIdentity__subscribeListeners() {
-    if (!ppmm) {
-      return;
-    }
-    for (let message of this.messages) {
-      ppmm.addMessageListener(message, this);
-    }
-  },
-
-  _unsubscribeListeners: function DOMIdentity__unsubscribeListeners() {
-    for (let message of this.messages) {
-      ppmm.removeMessageListener(message, this);
-    }
-    ppmm = null;
-  },
-
-  _watch: function DOMIdentity__watch(message, targetMM, principal) {
-    log("DOMIdentity__watch: " + message.id + " - " + principal);
-    let context = this.newContext(message, targetMM, principal);
-    this.getService(message).RP.watch(context);
-  },
-
-  _unwatch: function DOMIdentity_unwatch(message, targetMM) {
-    log("DOMIDentity__unwatch: " + message.id);
-    // If watch failed for some reason (e.g., exception thrown because RP did
-    // not have the right callbacks, we don't want unwatch to throw, because it
-    // will break the process of releasing the page's resources and leak
-    // memory.
-    let service = this.getService(message);
-    if (service && service.RP) {
-      service.RP.unwatch(message.id, targetMM);
-      this.deleteContextForMM(targetMM);
-      return;
-    }
-    log("Can't find a service to unwatch() for " + message.id);
-  },
-
-  _request: function DOMIdentity__request(message) {
-    let service = this.getService(message);
-    if (service && service.RP) {
-      service.RP.request(message.id, message);
-      return;
-    }
-    log("No context in which to call request(); Did you call watch() first?");
-  },
-
-  _logout: function DOMIdentity__logout(message) {
-    let service = this.getService(message);
-    if (service && service.RP) {
-      service.RP.logout(message.id, message.origin, message);
-      return;
-    }
-    log("No context in which to call logout(); Did you call watch() first?");
-  },
-
-  _childProcessShutdown: function DOMIdentity__childProcessShutdown(targetMM) {
-    if (!this.hasContextForMM(targetMM)) {
-      return;
-    }
-
-    let service = this.getContextForMM(targetMM);
-    if (service && service.RP) {
-      service.RP.childProcessShutdown(targetMM);
-    }
-
-    this.deleteContextForMM(targetMM);
-
-    let options = makeMessageObject({messageManager: targetMM, id: null, origin: null});
-    Services.obs.notifyObservers({wrappedJSObject: options}, "identity-child-process-shutdown", null);
-  },
-
-  _beginProvisioning: function DOMIdentity__beginProvisioning(message, targetMM) {
-    let context = new IDPProvisioningContext(message.id, message.origin,
-                                             targetMM);
-    this.getService(message).IDP.beginProvisioning(context);
-  },
-
-  _genKeyPair: function DOMIdentity__genKeyPair(message) {
-    this.getService(message).IDP.genKeyPair(message.id);
-  },
-
-  _registerCertificate: function DOMIdentity__registerCertificate(message) {
-    this.getService(message).IDP.registerCertificate(message.id, message.cert);
-  },
-
-  _provisioningFailure: function DOMIdentity__provisioningFailure(message) {
-    this.getService(message).IDP.raiseProvisioningFailure(message.id, message.reason);
-  },
-
-  _beginAuthentication: function DOMIdentity__beginAuthentication(message, targetMM) {
-    let context = new IDPAuthenticationContext(message.id, message.origin,
-                                               targetMM);
-    this.getService(message).IDP.beginAuthentication(context);
-  },
-
-  _completeAuthentication: function DOMIdentity__completeAuthentication(message) {
-    this.getService(message).IDP.completeAuthentication(message.id);
-  },
-
-  _authenticationFailure: function DOMIdentity__authenticationFailure(message) {
-    this.getService(message).IDP.cancelAuthentication(message.id);
-  }
-};
-
-// Object is initialized by nsIDService.js
deleted file mode 100644
--- a/dom/identity/Identity.manifest
+++ /dev/null
@@ -1,8 +0,0 @@
-# nsDOMIdentity.js
-component {210853d9-2c97-4669-9761-b1ab9cbf57ef} nsDOMIdentity.js
-contract @mozilla.org/identity/manager;1 {210853d9-2c97-4669-9761-b1ab9cbf57ef}
-
-# nsIDService.js (initialization on startup)
-component {4e0a0e98-b1d3-4745-a1eb-f815199dd06b} nsIDService.js
-contract @mozilla.org/dom/identity/service;1 {4e0a0e98-b1d3-4745-a1eb-f815199dd06b}
-category app-startup IDService @mozilla.org/dom/identity/service;1
deleted file mode 100644
--- a/dom/identity/moz.build
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-EXTRA_COMPONENTS += [
-    'Identity.manifest',
-    'nsDOMIdentity.js',
-    'nsIDService.js',
-]
-
-EXTRA_PP_JS_MODULES += [
-    'DOMIdentity.jsm',
-]
-
-MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
deleted file mode 100644
--- a/dom/identity/nsDOMIdentity.js
+++ /dev/null
@@ -1,800 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-const PREF_DEBUG = "toolkit.identity.debug";
-const PREF_ENABLED = "dom.identity.enabled";
-
-// Bug 822450: Workaround for Bug 821740.  When testing with marionette,
-// relax navigator.id.request's requirement that it be handling native
-// events.  Synthetic marionette events are ok.
-const PREF_SYNTHETIC_EVENTS_OK = "dom.identity.syntheticEventsOk";
-
-// Maximum length of a string that will go through IPC
-const MAX_STRING_LENGTH = 2048;
-// Maximum number of times navigator.id.request can be called for a document
-const MAX_RP_CALLS = 100;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "checkDeprecated",
-                                  "resource://gre/modules/identity/IdentityUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "checkRenamed",
-                                  "resource://gre/modules/identity/IdentityUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "objectCopy",
-                                  "resource://gre/modules/identity/IdentityUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "makeMessageObject",
-                                  "resource://gre/modules/identity/IdentityUtils.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
-                                   "@mozilla.org/uuid-generator;1",
-                                   "nsIUUIDGenerator");
-
-// This is the child process corresponding to nsIDOMIdentity
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsIMessageSender");
-
-
-const ERRORS = {
-  "ERROR_INVALID_ASSERTION_AUDIENCE":
-    "Assertion audience may not differ from origin",
-  "ERROR_REQUEST_WHILE_NOT_HANDLING_USER_INPUT":
-    "The request() method may only be invoked when handling user input",
-};
-
-function nsDOMIdentity() {
-}
-
-nsDOMIdentity.prototype = {
-
-  // require native events unless syntheticEventsOk is set
-  get nativeEventsRequired() {
-    if (Services.prefs.prefHasUserValue(PREF_SYNTHETIC_EVENTS_OK) &&
-        (Services.prefs.getPrefType(PREF_SYNTHETIC_EVENTS_OK) ===
-         Ci.nsIPrefBranch.PREF_BOOL)) {
-      return !Services.prefs.getBoolPref(PREF_SYNTHETIC_EVENTS_OK);
-    }
-    return true;
-  },
-
-  reportErrors: function(message) {
-    let onerror = function() {};
-    if (this._rpWatcher && this._rpWatcher.onerror) {
-      onerror = this._rpWatcher.onerror;
-    }
-
-    message.errors.forEach((error) => {
-      // Report an error string to content
-      Cu.reportError(ERRORS[error]);
-
-      // Report error code to RP callback, if available
-      onerror(error);
-    });
-  },
-
-  /**
-   * Relying Party (RP) APIs
-   */
-
-  watch: function nsDOMIdentity_watch(aOptions = {}) {
-    aOptions = Cu.waiveXrays(aOptions);
-    if (this._rpWatcher) {
-      // For the initial release of Firefox Accounts, we support callers who
-      // invoke watch() either for Firefox Accounts, or Persona, but not both.
-      // In the future, we may wish to support the dual invocation (say, for
-      // packaged apps so they can sign users in who reject the app's request
-      // to sign in with their Firefox Accounts identity).
-      throw new Error("navigator.id.watch was already called");
-    }
-
-    assertCorrectCallbacks(aOptions);
-
-    let message = this.DOMIdentityMessage(aOptions);
-
-    // loggedInUser vs loggedInEmail
-    // https://developer.mozilla.org/en-US/docs/DOM/navigator.id.watch
-    // This parameter, loggedInUser, was renamed from loggedInEmail in early
-    // September, 2012. Both names will continue to work for the time being,
-    // but code should be changed to use loggedInUser instead.
-    checkRenamed(aOptions, "loggedInEmail", "loggedInUser");
-
-    // Bad IPC or IDL converts null and undefined to "null" and "undefined".
-    // We can't assign to aOptions, which complicates the workaround.
-    message["loggedInUser"] = aOptions["loggedInUser"];
-    if (message.loggedInUser == "null" || message.loggedInUser == "undefined") {
-      message.loggedInUser = null;
-    }
-
-    if (message.loggedInUser) {
-      if (typeof(message.loggedInUser) !== "string") {
-        throw new Error("loggedInUser must be a String or null");
-      }
-
-      // TODO: Bug 767610 - check email format.
-      // See HTMLInputElement::IsValidEmailAddress
-      if (aOptions["loggedInUser"].indexOf("@") == -1
-          || aOptions["loggedInUser"].length > MAX_STRING_LENGTH) {
-        throw new Error("loggedInUser is not valid");
-      }
-    }
-    this._log("loggedInUser: " + message.loggedInUser);
-
-    this._rpWatcher = aOptions;
-    this._rpWatcher.audience = message.audience;
-
-    if (message.errors.length) {
-      this.reportErrors(message);
-      // We don't delete the rpWatcher object, because we don't want the
-      // broken client to be able to call watch() any more.  It's broken.
-      return;
-    }
-    this._mm.sendAsyncMessage(
-      "Identity:RP:Watch",
-      message,
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  request: function nsDOMIdentity_request(aOptions = {}) {
-    aOptions = Cu.waiveXrays(aOptions);
-    this._log("request: " + JSON.stringify(aOptions));
-
-    // Has the caller called watch() before this?
-    if (!this._rpWatcher) {
-      throw new Error("navigator.id.request called before navigator.id.watch");
-    }
-    if (this._rpCalls > MAX_RP_CALLS) {
-      throw new Error("navigator.id.request called too many times");
-    }
-
-    let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
-                           .getInterface(Ci.nsIDOMWindowUtils);
-
-    let message = this.DOMIdentityMessage(aOptions);
-
-    // We permit calling of request() outside of a user input handler only when
-    // a certified or privileged app is calling, or when we are handling the
-    // (deprecated) get() or getVerifiedEmail() calls, which make use of an RP
-    // context marked as _internal.
-
-    if (!aOptions._internal &&
-        this._appStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED &&
-        this._appStatus !== Ci.nsIPrincipal.APP_STATUS_PRIVILEGED) {
-
-      // If the caller is not special in one of those ways, see if the user has
-      // preffed on 'syntheticEventsOk' (useful for testing); otherwise, if
-      // this is a non-native event, reject it.
-      let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
-                             .getInterface(Ci.nsIDOMWindowUtils);
-
-      if (!util.isHandlingUserInput && this.nativeEventsRequired) {
-        message.errors.push("ERROR_REQUEST_WHILE_NOT_HANDLING_USER_INPUT");
-      }
-    }
-
-    // Report and fail hard on any errors.
-    if (message.errors.length) {
-      this.reportErrors(message);
-      return;
-    }
-
-    if (aOptions) {
-      // Optional string properties
-      let optionalStringProps = ["privacyPolicy", "termsOfService"];
-      for (let propName of optionalStringProps) {
-        if (!aOptions[propName] || aOptions[propName] === "undefined")
-          continue;
-        if (typeof(aOptions[propName]) !== "string") {
-          throw new Error(propName + " must be a string representing a URL.");
-        }
-        if (aOptions[propName].length > MAX_STRING_LENGTH) {
-          throw new Error(propName + " is invalid.");
-        }
-        message[propName] = aOptions[propName];
-      }
-
-      if (aOptions["oncancel"]
-            && typeof(aOptions["oncancel"]) !== "function") {
-        throw new Error("oncancel is not a function");
-      } else {
-        // Store optional cancel callback for later.
-        this._onCancelRequestCallback = aOptions.oncancel;
-      }
-    }
-
-    this._rpCalls++;
-    this._mm.sendAsyncMessage(
-      "Identity:RP:Request",
-      message,
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  logout: function nsDOMIdentity_logout() {
-    if (!this._rpWatcher) {
-      throw new Error("navigator.id.logout called before navigator.id.watch");
-    }
-    if (this._rpCalls > MAX_RP_CALLS) {
-      throw new Error("navigator.id.logout called too many times");
-    }
-
-    this._rpCalls++;
-    let message = this.DOMIdentityMessage();
-
-    // Report and fail hard on any errors.
-    if (message.errors.length) {
-      this.reportErrors(message);
-      return;
-    }
-
-    this._mm.sendAsyncMessage(
-      "Identity:RP:Logout",
-      message,
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  /*
-   * Get an assertion.  This function is deprecated.  RPs are
-   * encouraged to use the observer API instead (watch + request).
-   */
-  get: function nsDOMIdentity_get(aCallback, aOptions) {
-    var opts = {};
-    aOptions = aOptions || {};
-
-    // We use the observer API (watch + request) to implement get().
-    // Because the caller can call get() and getVerifiedEmail() as
-    // many times as they want, we lift the restriction that watch() can
-    // only be called once.
-    this._rpWatcher = null;
-
-    // This flag tells internal_api.js (in the shim) to record in the
-    // login parameters whether the assertion was acquired silently or
-    // with user interaction.
-    opts._internal = true;
-
-    opts.privacyPolicy = aOptions.privacyPolicy || undefined;
-    opts.termsOfService = aOptions.termsOfService || undefined;
-    opts.privacyURL = aOptions.privacyURL || undefined;
-    opts.tosURL = aOptions.tosURL || undefined;
-    opts.siteName = aOptions.siteName || undefined;
-    opts.siteLogo = aOptions.siteLogo || undefined;
-
-    opts.oncancel = function get_oncancel() {
-      if (aCallback) {
-        aCallback(null);
-        aCallback = null;
-      }
-    };
-
-    if (checkDeprecated(aOptions, "silent")) {
-      // Silent has been deprecated, do nothing. Placing the check here
-      // prevents the callback from being called twice, once with null and
-      // once after internalWatch has been called. See issue #1532:
-      // https://github.com/mozilla/browserid/issues/1532
-      if (aCallback) {
-        setTimeout(function() { aCallback(null); }, 0);
-      }
-      return;
-    }
-
-    // Get an assertion by using our observer api: watch + request.
-    var self = this;
-    this.watch({
-      _internal: true,
-      onlogin: function get_onlogin(assertion, internalParams) {
-        if (assertion && aCallback && internalParams && !internalParams.silent) {
-          aCallback(assertion);
-          aCallback = null;
-        }
-      },
-      onlogout: function get_onlogout() {},
-      onready: function get_onready() {
-        self.request(opts);
-      }
-    });
-  },
-
-  getVerifiedEmail: function nsDOMIdentity_getVerifiedEmail(aCallback) {
-    Cu.reportError("WARNING: getVerifiedEmail has been deprecated");
-    this.get(aCallback, {});
-  },
-
-  /**
-   *  Identity Provider (IDP) Provisioning APIs
-   */
-
-  beginProvisioning: function nsDOMIdentity_beginProvisioning(aCallback) {
-    this._log("beginProvisioning");
-    if (this._beginProvisioningCallback) {
-      throw new Error("navigator.id.beginProvisioning already called.");
-    }
-    if (!aCallback || typeof(aCallback) !== "function") {
-      throw new Error("beginProvisioning callback is required.");
-    }
-
-    this._beginProvisioningCallback = aCallback;
-    this._mm.sendAsyncMessage(
-      "Identity:IDP:BeginProvisioning",
-      this.DOMIdentityMessage(),
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  genKeyPair: function nsDOMIdentity_genKeyPair(aCallback) {
-    this._log("genKeyPair");
-    if (!this._beginProvisioningCallback) {
-      throw new Error("navigator.id.genKeyPair called outside of provisioning");
-    }
-    if (this._genKeyPairCallback) {
-      throw new Error("navigator.id.genKeyPair already called.");
-    }
-    if (!aCallback || typeof(aCallback) !== "function") {
-      throw new Error("genKeyPair callback is required.");
-    }
-
-    this._genKeyPairCallback = aCallback;
-    this._mm.sendAsyncMessage(
-      "Identity:IDP:GenKeyPair",
-      this.DOMIdentityMessage(),
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  registerCertificate: function nsDOMIdentity_registerCertificate(aCertificate) {
-    this._log("registerCertificate");
-    if (!this._genKeyPairCallback) {
-      throw new Error("navigator.id.registerCertificate called outside of provisioning");
-    }
-    if (this._provisioningEnded) {
-      throw new Error("Provisioning already ended");
-    }
-    this._provisioningEnded = true;
-
-    let message = this.DOMIdentityMessage();
-    message.cert = aCertificate;
-    this._mm.sendAsyncMessage(
-      "Identity:IDP:RegisterCertificate",
-      message,
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  raiseProvisioningFailure: function nsDOMIdentity_raiseProvisioningFailure(aReason) {
-    this._log("raiseProvisioningFailure '" + aReason + "'");
-    if (this._provisioningEnded) {
-      throw new Error("Provisioning already ended");
-    }
-    if (!aReason || typeof(aReason) != "string") {
-      throw new Error("raiseProvisioningFailure reason is required");
-    }
-    this._provisioningEnded = true;
-
-    let message = this.DOMIdentityMessage();
-    message.reason = aReason;
-    this._mm.sendAsyncMessage(
-      "Identity:IDP:ProvisioningFailure",
-      message,
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  /**
-   *  Identity Provider (IDP) Authentication APIs
-   */
-
-  beginAuthentication: function nsDOMIdentity_beginAuthentication(aCallback) {
-    this._log("beginAuthentication");
-    if (this._beginAuthenticationCallback) {
-      throw new Error("navigator.id.beginAuthentication already called.");
-    }
-    if (typeof(aCallback) !== "function") {
-      throw new Error("beginAuthentication callback is required.");
-    }
-    if (!aCallback || typeof(aCallback) !== "function") {
-      throw new Error("beginAuthentication callback is required.");
-    }
-
-    this._beginAuthenticationCallback = aCallback;
-    this._mm.sendAsyncMessage(
-      "Identity:IDP:BeginAuthentication",
-      this.DOMIdentityMessage(),
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  completeAuthentication: function nsDOMIdentity_completeAuthentication() {
-    if (this._authenticationEnded) {
-      throw new Error("Authentication already ended");
-    }
-    if (!this._beginAuthenticationCallback) {
-      throw new Error("navigator.id.completeAuthentication called outside of authentication");
-    }
-    this._authenticationEnded = true;
-
-    this._mm.sendAsyncMessage(
-      "Identity:IDP:CompleteAuthentication",
-      this.DOMIdentityMessage(),
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  raiseAuthenticationFailure: function nsDOMIdentity_raiseAuthenticationFailure(aReason) {
-    if (this._authenticationEnded) {
-      throw new Error("Authentication already ended");
-    }
-    if (!aReason || typeof(aReason) != "string") {
-      throw new Error("raiseProvisioningFailure reason is required");
-    }
-
-    let message = this.DOMIdentityMessage();
-    message.reason = aReason;
-    this._mm.sendAsyncMessage(
-      "Identity:IDP:AuthenticationFailure",
-      message,
-      null,
-      this._window.document.nodePrincipal
-    );
-  },
-
-  /**
-   * Called during init and shutdown.
-   */
-  _initializeState: function nsDOMIdentity__initializeState() {
-    // Some state to prevent abuse
-    // Limit the number of calls to .request
-    this._rpCalls = 0;
-    this._provisioningEnded = false;
-    this._authenticationEnded = false;
-
-    this._rpWatcher = null;
-    this._onCancelRequestCallback = null;
-    this._beginProvisioningCallback = null;
-    this._genKeyPairCallback = null;
-    this._beginAuthenticationCallback = null;
-  },
-
-  // nsIMessageListener
-  receiveMessage: function nsDOMIdentity_receiveMessage(aMessage) {
-    let msg = aMessage.json;
-
-    // Is this message intended for this window?
-    if (msg.id != this._id) {
-      return;
-    }
-
-    switch (aMessage.name) {
-      case "Identity:ResetState":
-        if (!this._debug) {
-          return;
-        }
-        this._initializeState();
-        Services.obs.notifyObservers(null, "identity-DOM-state-reset", this._id);
-        break;
-      case "Identity:RP:Watch:OnLogin":
-        // Do we have a watcher?
-        if (!this._rpWatcher) {
-          this._log("WARNING: Received OnLogin message, but there is no RP watcher");
-          return;
-        }
-
-        if (this._rpWatcher.onlogin) {
-          if (this._rpWatcher._internal) {
-            this._rpWatcher.onlogin(msg.assertion, msg._internalParams);
-          } else {
-            this._rpWatcher.onlogin(msg.assertion);
-          }
-        }
-        break;
-      case "Identity:RP:Watch:OnLogout":
-        // Do we have a watcher?
-        if (!this._rpWatcher) {
-          this._log("WARNING: Received OnLogout message, but there is no RP watcher");
-          return;
-        }
-
-        if (this._rpWatcher.onlogout) {
-          this._rpWatcher.onlogout();
-        }
-        break;
-      case "Identity:RP:Watch:OnReady":
-        // Do we have a watcher?
-        if (!this._rpWatcher) {
-          this._log("WARNING: Received OnReady message, but there is no RP watcher");
-          return;
-        }
-
-        if (this._rpWatcher.onready) {
-          this._rpWatcher.onready();
-        }
-        break;
-      case "Identity:RP:Watch:OnCancel":
-        // Do we have a watcher?
-        if (!this._rpWatcher) {
-          this._log("WARNING: Received OnCancel message, but there is no RP " +
-                    "watcher");
-          return;
-        }
-
-        if (this._onCancelRequestCallback) {
-          this._onCancelRequestCallback();
-        }
-        break;
-      case "Identity:RP:Watch:OnError":
-        if (!this._rpWatcher) {
-          this._log("WARNING: Received OnError message, but there is no RP " +
-                    "watcher");
-          return;
-        }
-
-        if (this._rpWatcher.onerror) {
-          this._rpWatcher.onerror(JSON.stringify({name: msg.message.error}));
-        }
-        break;
-      case "Identity:IDP:CallBeginProvisioningCallback":
-        this._callBeginProvisioningCallback(msg);
-        break;
-      case "Identity:IDP:CallGenKeyPairCallback":
-        this._callGenKeyPairCallback(msg);
-        break;
-      case "Identity:IDP:CallBeginAuthenticationCallback":
-        this._callBeginAuthenticationCallback(msg);
-        break;
-    }
-  },
-
-  _callGenKeyPairCallback: function nsDOMIdentity__callGenKeyPairCallback(message) {
-    // create a pubkey object that works
-    let chrome_pubkey = JSON.parse(message.publicKey);
-
-    // bunch of stuff to create a proper object in window context
-    function genPropDesc(value) {
-      return {
-        enumerable: true, configurable: true, writable: true, value: value
-      };
-    }
-
-    let propList = {};
-    for (let k in chrome_pubkey) {
-      propList[k] = genPropDesc(chrome_pubkey[k]);
-    }
-
-    let pubkey = Cu.createObjectIn(this._window);
-    Object.defineProperties(pubkey, propList);
-    Cu.makeObjectPropsNormal(pubkey);
-
-    // do the callback
-    this._genKeyPairCallback(pubkey);
-  },
-
-  _callBeginProvisioningCallback:
-      function nsDOMIdentity__callBeginProvisioningCallback(message) {
-    let identity = message.identity;
-    let certValidityDuration = message.certDuration;
-    this._beginProvisioningCallback(identity,
-                                    certValidityDuration);
-  },
-
-  _callBeginAuthenticationCallback:
-      function nsDOMIdentity__callBeginAuthenticationCallback(message) {
-    let identity = message.identity;
-    this._beginAuthenticationCallback(identity);
-  },
-
-  /**
-   * Helper to create messages to send using a message manager.
-   * Pass through user options if they are not functions.  Always
-   * overwrite id, origin, audience, and appStatus.  The caller
-   * does not get to set those.
-   */
-  DOMIdentityMessage: function DOMIdentityMessage(aOptions) {
-    aOptions = aOptions || {};
-    let message = {
-      errors: []
-    };
-
-    objectCopy(aOptions, message);
-
-    // outer window id
-    message.id = this._id;
-
-    // window origin
-    message.origin = this._origin;
-
-    // Normally the window origin will be the audience in assertions.  On b2g,
-    // certified apps have the power to override this and declare any audience
-    // the want.  Privileged apps can also declare a different audience, as
-    // long as it is the same as the origin specified in their manifest files.
-    // All other apps are stuck with b2g origins of the form app://{guid}.
-    // Since such an origin is meaningless for the purposes of verification,
-    // they will have to jump through some hoops to sign in: Specifically, they
-    // will have to host their sign-in flows and DOM API requests in an iframe,
-    // have the iframe xhr post assertions up to their server for verification,
-    // and then post-message the results down to their app.
-    let _audience = message.origin;
-    if (message.audience && message.audience != message.origin) {
-      if (this._appStatus === Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
-        _audience = message.audience;
-        this._log("Certified app setting assertion audience: " + _audience);
-      } else {
-        message.errors.push("ERROR_INVALID_ASSERTION_AUDIENCE");
-      }
-    }
-
-    // Replace any audience supplied by the RP with one that has been sanitised
-    message.audience = _audience;
-
-    this._log("DOMIdentityMessage: " + JSON.stringify(message));
-
-    return makeMessageObject(message);
-  },
-
- /**
-  * Internal methods that are not exposed to content.
-  * See dom/webidl/Identity.webidl for the public interface.
-  */
-  // nsIObserver
-  observe: function nsDOMIdentityInternal_observe(aSubject, aTopic, aData) {
-    let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
-    if (wId != this._innerWindowID) {
-      return;
-    }
-
-    this.uninit();
-
-    Services.obs.removeObserver(this, "inner-window-destroyed");
-    this._initializeState();
-
-    // TODO: Also send message to DOMIdentity notifiying window is no longer valid
-    // ie. in the case that the user closes the auth. window and we need to know.
-
-    try {
-      for (let msgName of this._messages) {
-        this._mm.removeMessageListener(msgName, this);
-      }
-    } catch (ex) {
-      // Avoid errors when removing more than once.
-    }
-
-    this._mm = null;
-  },
-
-  //  Because we implement nsIDOMGlobalPropertyInitializer, our init() method
-  //  is invoked with content window as its single argument.
-  init: function nsDOMIdentityInternal_init(aWindow) {
-    if (Services.prefs.getPrefType(PREF_ENABLED) != Ci.nsIPrefBranch.PREF_BOOL
-        || !Services.prefs.getBoolPref(PREF_ENABLED)) {
-      return null;
-    }
-
-    this._debug =
-      Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
-      && Services.prefs.getBoolPref(PREF_DEBUG);
-
-    // Setup identifiers for current window.
-    let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                      .getInterface(Ci.nsIDOMWindowUtils);
-
-    // To avoid cross-process windowId collisions, use a uuid as an
-    // almost certainly unique identifier.
-    //
-    // XXX Bug 869182 - use a combination of child process id and
-    // innerwindow id to construct the unique id.
-    this._id = uuidgen.generateUUID().toString();
-    this._window = aWindow;
-
-    // nsDOMIdentity needs to know our _id, so this goes after
-    // its creation.
-    this._initializeState();
-
-    // Store window and origin URI.
-    this._window = aWindow;
-    this._origin = aWindow.document.nodePrincipal.origin;
-    this._appStatus = aWindow.document.nodePrincipal.appStatus;
-    this._appId = aWindow.document.nodePrincipal.appId;
-
-    this._log("init was called from " + aWindow.document.location);
-
-    this._mm = cpmm;
-
-    // Setup listeners for messages from parent process.
-    this._messages = [
-      "Identity:ResetState",
-      "Identity:RP:Watch:OnLogin",
-      "Identity:RP:Watch:OnLogout",
-      "Identity:RP:Watch:OnReady",
-      "Identity:RP:Watch:OnCancel",
-      "Identity:RP:Watch:OnError",
-      "Identity:IDP:CallBeginProvisioningCallback",
-      "Identity:IDP:CallGenKeyPairCallback",
-      "Identity:IDP:CallBeginAuthenticationCallback"
-    ];
-    this._messages.forEach(function(msgName) {
-      this._mm.addMessageListener(msgName, this);
-    }, this);
-
-    // Setup observers so we can remove message listeners.
-    Services.obs.addObserver(this, "inner-window-destroyed", false);
-  },
-
-  uninit: function DOMIdentity_uninit() {
-    this._log("nsDOMIdentity uninit() " + this._id);
-    this._mm.sendAsyncMessage(
-      "Identity:RP:Unwatch",
-      { id: this._id }
-    );
-   },
-
-  // Private.
-  _log: function nsDOMIdentityInternal__log(msg) {
-    if (!this._debug) {
-      return;
-    }
-    dump("nsDOMIdentity (" + this._id + "): " + msg + "\n");
-  },
-
-  // Component setup.
-  classID: Components.ID("{210853d9-2c97-4669-9761-b1ab9cbf57ef}"),
-
-  QueryInterface: XPCOMUtils.generateQI([
-      Ci.nsIMessageListener,
-      Ci.nsIObserver,
-      Ci.nsIDOMGlobalPropertyInitializer
-  ]),
-
-  classInfo: XPCOMUtils.generateCI({
-    classID: Components.ID("{210853d9-2c97-4669-9761-b1ab9cbf57ef}"),
-    contractID: "@mozilla.org/dom/identity;1",
-    interfaces: [],
-    classDescription: "Identity DOM Implementation"
-  })
-};
-
-function assertCorrectCallbacks(aOptions) {
-  // The relying party (RP) provides callbacks on watch().
-  //
-  // In the future, BrowserID will probably only require an onlogin()
-  // callback, lifting the requirement that BrowserID handle logged-in
-  // state management for RPs.  See
-  // https://github.com/mozilla/id-specs/blob/greenfield/browserid/api-rp.md
-  //
-  // However, Firefox Accounts requires callers to provide onlogout(),
-  // onready(), and also supports an onerror() callback.
-
-  let requiredCallbacks = ["onlogin"];
-  let optionalCallbacks = ["onlogout", "onready", "onerror"];
-
-  if (aOptions.wantIssuer == "firefox-accounts") {
-    requiredCallbacks = ["onlogin", "onlogout", "onready"];
-    optionalCallbacks = ["onerror"];
-  }
-
-  for (let cbName of requiredCallbacks) {
-    if (typeof(aOptions[cbName]) != "function") {
-      throw new Error(cbName + " callback is required.");
-    }
-  }
-
-  for (let cbName of optionalCallbacks) {
-    if (aOptions[cbName] && typeof(aOptions[cbName]) != "function") {
-      throw new Error(cbName + " must be a function");
-    }
-  }
-}
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsDOMIdentity]);
deleted file mode 100644
--- a/dom/identity/nsIDService.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-this.IDService = function IDService() {
-  this.wrappedJSObject = this;
-};
-
-this.IDService.prototype = {
-  classID: Components.ID("{4e0a0e98-b1d3-4745-a1eb-f815199dd06b}"),
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
-                                         Ci.nsISupportsWeakReference]),
-
-  observe: function observe(subject, topic, data) {
-    switch (topic) {
-      case "app-startup":
-        Services.obs.addObserver(this, "final-ui-startup", true);
-        break;
-      case "final-ui-startup":
-        // Startup DOMIdentity.jsm
-        Cu.import("resource://gre/modules/DOMIdentity.jsm");
-        DOMIdentity._init();
-        break;
-    }
-  }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([IDService]);
deleted file mode 100644
--- a/dom/identity/tests/mochitest/chrome.ini
+++ /dev/null
@@ -1,18 +0,0 @@
-[DEFAULT]
-skip-if = buildapp == 'b2g'
-
-support-files=
-  file_browserid_rp_ok.html
-  file_browserid_rp_noOnlogin.html
-  file_declareAudience.html
-  file_fxa_rp_ok.html
-  file_fxa_rp_noOnready.html
-  file_fxa_rp_noOnlogin.html
-  file_fxa_rp_noOnlogout.html
-  file_syntheticEvents.html
-
-[test_declareAudience.html]
-[test_rpHasValidCallbacks.html]
-skip-if = buildapp == 'mulet'
-[test_syntheticEvents.html]
-
deleted file mode 100644
--- a/dom/identity/tests/mochitest/file_browserid_rp_noOnlogin.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-  <!--
-  RPs have the correct callbacks for BrowserID or Firefox Accounts
-  https://bugzilla.mozilla.org/show_bug.cgi?id=945363
-  -->
-<head>
-  <meta charset="utf-8">
-  <title>Test app for bug 945363</title>
-</head>
-
-<body>
-<script type="application/javascript;version=1.7">
-
-  // This is a bad RP.  It does not provide an onlogin callback.
-  // nsDOMIdentity will throw an exception when we call watch().
-
-  function postMessage(message) {
-    SpecialPowers.wrap(window).parent
-      .postMessage(JSON.stringify(message), "*");
-  }
-
-  let error = false;
-
-  window.addEventListener('load', function onLoad(event) {
-    window.removeEventListener('load', onLoad);
-    try {
-      navigator.mozId.watch({ });
-    } catch(ex) {
-      error = true;
-    }
-    postMessage({error: error});
-  }, false);
-
-
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/file_browserid_rp_ok.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-  <!--
-  RPs have the correct callbacks for BrowserID or Firefox Accounts
-  https://bugzilla.mozilla.org/show_bug.cgi?id=945363
-  -->
-<head>
-  <meta charset="utf-8">
-  <title>Test app for bug 945363</title>
-</head>
-
-<body>
-<script type="application/javascript;version=1.7">
-
-  // This is a happy RP.  It has the expected callbacks for BrowserID.
-
-  function postMessage(message) {
-    SpecialPowers.wrap(window).parent
-      .postMessage(JSON.stringify(message), "*");
-  }
-
-  let error = false;
-
-  window.addEventListener('load', function onLoad(event) {
-    window.removeEventListener('load', onLoad);
-    try {
-      navigator.mozId.watch({
-        onlogin: function() {},
-      });
-    } catch(ex) {
-      error = true;
-    }
-    postMessage({error: error});
-  }, false);
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/file_declareAudience.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-  <!--
-  Certified and packaged apps should be able to declare assertion audience.
-  https://bugzilla.mozilla.org/show_bug.cgi?id=947374
-  -->
-<head>
-  <meta charset="utf-8">
-  <title>Test app for bug 947374</title>
-</head>
-
-<body>
-    <div id='test'>
-<script type="application/javascript;version=1.8">
-
-  function postResults(message) {
-    doPostMessage(JSON.stringify(message), "*");
-  }
-
-  onmessage = function(event) {
-    try {
-      navigator.mozId.watch({
-        wantIssuer: "firefox-accounts",
-        audience: event.data.audience,
-        onready: function() {
-          try {
-            navigator.mozId.request();
-          } catch(e) {
-            postResults({
-              success: false,
-              error: e,
-              appIndex: event.data.appIndex
-            });
-          }
-        },
-        onlogin: function(backedAssertion) {
-          postResults({
-            success: true,
-            backedAssertion: backedAssertion,
-            appIndex: event.data.appIndex
-          });
-        },
-        onerror: function(error) {
-          postResults({
-            success: false,
-            error: error,
-            appIndex: event.data.appIndex
-          });
-        },
-
-        // onlogout will actually be called every time watch() is invoked,
-        // because fxa will find no signed-in user and so trigger logout.
-        // For this test, though, we don't care and just ignore logout.
-        onlogout: function () {},
-      });
-    } catch (e) {
-      postResults({
-        success: false,
-        error: e,
-        appIndex: event.data.appIndex
-      });
-    }
-  };
-
-</script>
-</div>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/file_fxa_rp_noOnlogin.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-  <!--
-  RPs have the correct callbacks for BrowserID or Firefox Accounts
-  https://bugzilla.mozilla.org/show_bug.cgi?id=945363
-  -->
-<head>
-  <meta charset="utf-8">
-  <title>Test app for bug 945363</title>
-</head>
-
-<body>
-<script type="application/javascript;version=1.7">
-
-  // This is a bad Firefox Accounts RP.  It has no onlogin callback.
-  // nsDOMIdentity will throw an exception.
-
-  function postMessage(message) {
-    SpecialPowers.wrap(window).parent
-      .postMessage(JSON.stringify(message), "*");
-  }
-
-  let error = false;
-
-  window.addEventListener('load', function onLoad(event) {
-    window.removeEventListener('load', onLoad);
-    try {
-      navigator.mozId.watch({
-        wantIssuer: "firefox-accounts",
-        onready: function() {},
-        onlogout: function() {},
-      });
-    } catch(ex) {
-      error = true;
-    }
-    postMessage({error: error});
-  }, false);
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/file_fxa_rp_noOnlogout.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-  <!--
-  RPs have the correct callbacks for BrowserID or Firefox Accounts
-  https://bugzilla.mozilla.org/show_bug.cgi?id=945363
-  -->
-<head>
-  <meta charset="utf-8">
-  <title>Test app for bug 945363</title>
-</head>
-
-<body>
-<script type="application/javascript;version=1.7">
-
-  // This is a bad Firefox Accounts RP.  It has no onlogout callback.
-  // nsDOMIdentity will throw an exception.
-
-  function postMessage(message) {
-    SpecialPowers.wrap(window).parent
-      .postMessage(JSON.stringify(message), "*");
-  }
-
-  let error = false;
-
-  window.addEventListener('load', function onLoad(event) {
-    window.removeEventListener('load', onLoad);
-    try {
-      navigator.mozId.watch({
-        wantIssuer: "firefox-accounts",
-        onlogin: function() {},
-        onready: function() {},
-      });
-    } catch(ex) {
-      error = true;
-    }
-    postMessage({error: error});
-  }, false);
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/file_fxa_rp_noOnready.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-  <!--
-  RPs have the correct callbacks for BrowserID or Firefox Accounts
-  https://bugzilla.mozilla.org/show_bug.cgi?id=945363
-  -->
-<head>
-  <meta charset="utf-8">
-  <title>Test app for bug 945363</title>
-</head>
-
-<body>
-<script type="application/javascript;version=1.7">
-
-  // This is a bad Firefox Accounts RP.  It has no onready callback.
-  // nsDOMIdentity will throw an exception.
-
-  function postMessage(message) {
-    SpecialPowers.wrap(window).parent
-      .postMessage(JSON.stringify(message), "*");
-  }
-
-  let error = false;
-
-  window.addEventListener('load', function onLoad(event) {
-    window.removeEventListener('load', onLoad);
-    try {
-      navigator.mozId.watch({
-        wantIssuer: "firefox-accounts",
-        onlogin: function() {},
-        onlogout: function() {},
-      });
-    } catch(ex) {
-      error = true;
-    }
-    postMessage({error: error});
-  }, false);
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/file_fxa_rp_ok.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-  <!--
-  RPs have the correct callbacks for BrowserID or Firefox Accounts
-  https://bugzilla.mozilla.org/show_bug.cgi?id=945363
-  -->
-<head>
-  <meta charset="utf-8">
-  <title>Test app for bug 945363</title>
-</head>
-
-<body>
-<script type="application/javascript;version=1.7">
-
-  // This is a happy RP.  It has the expected callbacks for Firefox Accounts.
-
-  function postMessage(message) {
-    SpecialPowers.wrap(window).parent
-      .postMessage(JSON.stringify(message), "*");
-  }
-
-  let error = false;
-
-  window.addEventListener('load', function onLoad(event) {
-    window.removeEventListener('load', onLoad);
-    try {
-      navigator.mozId.watch({
-        wantIssuer: "firefox-accounts",
-        onready: function() {},
-        onlogin: function() {},
-        onlogout: function() {},
-      });
-    } catch(ex) {
-      error = true;
-    }
-    postMessage({error: error});
-  }, false);
-
-</script>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/file_syntheticEvents.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-  <!--
-  Certified and privileged apps can call mozId outside an event handler
-  Certified apps:  https://bugzilla.mozilla.org/show_bug.cgi?id=971379
-  Privileged apps: https://bugzilla.mozilla.org/show_bug.cgi?id=982460
-  -->
-<head>
-  <meta charset="utf-8">
-  <title>Test app for bug 971379</title>
-</head>
-
-<body>
-    <div id='test'>
-<script type="application/javascript;version=1.8">
-
-  function postResults(message) {
-    doPostMessage(JSON.stringify(message), "*");
-  }
-
-  onmessage = function(event) {
-    navigator.mozId.watch({
-      wantIssuer: event.data.wantIssuer,
-      onready: function() {
-        try {
-          navigator.mozId.request();
-        } catch(e) {
-          postResults({
-            success: false,
-            error: e,
-            appIndex: event.data.appIndex
-          });
-        }
-      },
-      onlogin: function(backedAssertion) {
-        postResults({
-          success: true,
-          backedAssertion: backedAssertion,
-          appIndex: event.data.appIndex
-        });
-      },
-      onerror: function(error) {
-        postResults({
-          success: false,
-          error: error,
-          appIndex: event.data.appIndex
-        });
-      },
-      onlogout: function() {},
-    });
-  };
-
-</script>
-</div>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/test_declareAudience.html
+++ /dev/null
@@ -1,289 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-  https://bugzilla.mozilla.org/show_bug.cgi?id=947374
--->
-<head>
-  <meta charset="utf-8">
-  <title>Certified apps can changed the default audience of an assertion -- Bug 947374</title>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=947374">Mozilla Bug 947374</a>
-<p id="display"></p>
-<div id="content">
-
-</div>
-<pre id="test">
-<script type="application/javascript;version=1.8">
-
-SimpleTest.waitForExplicitFinish();
-
-Components.utils.import("resource://gre/modules/Promise.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/identity/jwcrypto.jsm");
-Components.utils.import("resource://gre/modules/identity/FirefoxAccounts.jsm");
-
-// quick check to make sure we can test apps:
-is("appStatus" in document.nodePrincipal, true,
-   "appStatus should be present in nsIPrincipal, if not the rest of this test will fail");
-
-// Mock the Firefox Accounts manager to generate a keypair and provide a fake
-// cert for the caller on each getAssertion request.
-function MockFXAManager() {}
-
-MockFXAManager.prototype = {
-  getAssertion: function(audience, options) {
-    // Always reject a request for a silent assertion, simulating the
-    // scenario in which there is no signed-in user to begin with.
-    if (options.silent) {
-      return Promise.resolve(null);
-    }
-
-    let deferred = Promise.defer();
-    jwcrypto.generateKeyPair("DS160", (err, kp) => {
-      if (err) {
-        return deferred.reject(err);
-      }
-      jwcrypto.generateAssertion("fake-cert", kp, audience, (err, assertion) => {
-        if (err) {
-          return deferred.reject(err);
-        }
-        return deferred.resolve(assertion);
-      });
-    });
-    return deferred.promise;
-  }
-};
-
-let originalManager = FirefoxAccounts.fxAccountsManager;
-FirefoxAccounts.fxAccountsManager = new MockFXAManager();
-
-// The manifests for these apps are all declared in
-// /testing/profiles/webapps_mochitest.json.  They are injected into the profile
-// by /testing/mochitest/runtests.py with the appropriate appStatus.  So we don't
-// have to manually install any apps.
-//
-// For each app, we will use the file_declareAudience.html content to populate an
-// iframe.  The iframe will request() a firefox accounts assertion.  It will then
-// postMessage the results of this experiment back down to us, and we will
-// compare it with the expected results.
-let apps = [
-  {
-    title: "an installed app, which should neither be able to use FxA, nor change audience",
-    manifest: "https://example.com/manifest.webapp",
-    appStatus: Components.interfaces.nsIPrincipal.APP_STATUS_INSTALLED,
-    origin: "https://example.com",
-    wantAudience: "https://i-cant-have-this.com",
-    uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_declareAudience.html",
-    expected: {
-      success: false,
-      underprivileged: true,
-    },
-  },
-  {
-    title: "an app's assertion audience should be its origin by default",
-    manifest: "https://example.com/manifest_priv.webapp",
-    appStatus: Components.interfaces.nsIPrincipal.APP_STATUS_PRIVILEGED,
-    origin: "https://example.com",
-    uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_declareAudience.html",
-    expected: {
-      success: true,
-      underprivileged: false,
-    },
-  },
-  {
-    title: "a privileged app, which may not have an audience other than its origin",
-    manifest: "https://example.com/manifest_priv.webapp",
-    appStatus: Components.interfaces.nsIPrincipal.APP_STATUS_PRIVILEGED,
-    origin: "https://example.com",
-    wantAudience: "https://i-like-pie.com",
-    uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_declareAudience.html",
-    expected: {
-      success: false,
-      underprivileged: true,
-    },
-  },
-  {
-    title: "a privileged app, which may declare an audience the same as its origin",
-    manifest: "https://example.com/manifest_priv.webapp",
-    appStatus: Components.interfaces.nsIPrincipal.APP_STATUS_PRIVILEGED,
-    origin: "https://example.com",
-    wantAudience: "https://example.com",
-    uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_declareAudience.html",
-    expected: {
-      success: true,
-      underprivileged: false,
-    },
-  },
-  {
-    title: "a certified app, which may do whatever it damn well pleases",
-    manifest: "https://example.com/manifest_cert.webapp",
-    appStatus: Components.interfaces.nsIPrincipal.APP_STATUS_CERTIFIED,
-    origin: "https://example.com",
-    wantAudience: "https://whatever-i-want.com",
-    uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_declareAudience.html",
-    expected: {
-      success: true,
-    },
-  },
-];
-
-let eventsReceived = 0;
-let testRunner = runTest();
-
-// Successful tests will send exactly one message.  But for error tests, we may
-// have more than one message from the onerror handler in the client.  So we keep
-// track of received errors; once they reach the expected count, we are done.
-function receiveMessage(event) {
-  let result = JSON.parse(event.data);
-  let app = apps[result.appIndex];
-  if (app.received) {
-    return;
-  }
-  apps[result.appIndex].received = true;
-
-  let expected = app.expected;
-
-  let expectedErrors = 0;
-  let receivedErrors = [];
-
-  if (expected.underprivileged) {
-    expectedErrors += 1;
-  }
-  if (expected.nopermission) {
-    expectedErrors += 1;
-  }
-
-  is(result.success, expected.success,
-     "Assertion request succeeds");
-
-  if (expected.success) {
-    // Confirm that the assertion audience and origin are as expected
-    let components = extractAssertionComponents(result.backedAssertion);
-    is(components.payload.aud, app.wantAudience || app.origin,
-       "Got desired assertion audience");
-  } else {
-    receivedErrors.push(result.error);
-  }
-
-
-  ok(receivedErrors.length === expectedErrors,
-     "Received errors should be equal to expected errors");
-
-  if (!expected.success && expected.underprivileged) {
-    ok(receivedErrors.indexOf("ERROR_INVALID_ASSERTION_AUDIENCE") > -1,
-       "Expect an error getting an assertion");
-  }
-
-  eventsReceived += 1;
-
-  if (eventsReceived === apps.length) {
-    window.removeEventListener("message", receiveMessage);
-
-    FirefoxAccounts.fxAccountsManager = originalManager;
-
-    SimpleTest.finish();
-
-    return;
-  }
-
-  testRunner.next();
-}
-
-window.addEventListener("message", receiveMessage, false, true);
-
-function runTest() {
-  let index;
-  for (let i = 0; i < apps.length; i++) {
-    let app = apps[i];
-    dump("\n\n** Testing " + app.title + "\n");
-
-    let iframe = document.createElement("iframe");
-
-    iframe.setAttribute("mozapp", app.manifest);
-    iframe.setAttribute("mozbrowser", "true");
-    iframe.src = app.uri;
-
-    document.getElementById("content").appendChild(iframe);
-
-    index = i;
-    (function(_index) {
-      iframe.addEventListener("load", function onLoad() {
-        iframe.removeEventListener("load", onLoad);
-
-        SpecialPowers.addPermission(
-          "firefox-accounts",
-          SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION,
-          iframe.contentDocument
-        );
-
-        let principal = iframe.contentDocument.nodePrincipal;
-        is(principal.appStatus, app.appStatus,
-           "Iframe's document.nodePrincipal has expected appStatus");
-
-        // Because the <iframe mozapp> can't parent its way back to us, we
-        // provide this handle it can use to postMessage to us.
-        Components.utils.exportFunction(window.postMessage.bind(window), iframe.contentWindow, {defineAs: 'doPostMessage'});
-
-        // Test what we want to test, viz. whether or not the app can request
-        // an assertion with an audience the same as or different from its
-        // origin.  The client will post back its success or failure in procuring
-        // an identity assertion from Firefox Accounts.
-        iframe.contentWindow.postMessage({
-          audience: app.wantAudience,
-          appIndex: _index
-        }, "*");
-      }, false);
-    })(index);
-    yield undefined;
-  }
-}
-
-function extractAssertionComponents(backedAssertion) {
-  let [_, signedObject] = backedAssertion.split("~");
-  let parts = signedObject.split(".");
-
-  let headerSegment = parts[0];
-  let payloadSegment = parts[1];
-  let cryptoSegment = parts[2];
-
-  let header = JSON.parse(base64UrlDecode(headerSegment));
-  let payload = JSON.parse(base64UrlDecode(payloadSegment));
-
-  return {header: header,
-          payload: payload,
-          headerSegment: headerSegment,
-          payloadSegment: payloadSegment,
-          cryptoSegment: cryptoSegment};
-};
-
-function base64UrlDecode(s) {
-  s = s.replace(/-/g, "+");
-  s = s.replace(/_/g, "/");
-  // Don't need to worry about reintroducing padding ('=='), since
-  // jwcrypto provides that.
-  return atob(s);
-}
-
-SpecialPowers.pushPrefEnv({"set":
-  [
-    ["dom.mozBrowserFramesEnabled", true],
-    ["dom.identity.enabled", true],
-    ["identity.fxaccounts.enabled", true],
-    ["toolkit.identity.debug", true],
-    ["dom.identity.syntheticEventsOk", true],
-    ["security.apps.privileged.CSP.default", "'inline-script';"],
-    ["security.apps.certified.CSP.default", "'inline-script';"],
-  ]},
-  function() {
-    testRunner.next();
-  }
-);
-
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/test_rpHasValidCallbacks.html
+++ /dev/null
@@ -1,97 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-  <!--
-  https://bugzilla.mozilla.org/show_bug.cgi?id=945363
-  -->
-<head>
-  <meta charset="utf-8">
-  <title>BrowserID and Firefox Accounts RPs provide requried callbacks - Bug 945363</title>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=945363">Mozilla Bug 945363</a>
-<p id="display"></p>
-<div id="content">
-
-</div>
-<pre id="test">
-<script type="application/javascript;version=1.7">
-
-/** Test for Bug 945363 **/
-
-const BASE_URL = "http://mochi.test:8888/chrome/dom/identity/tests/mochitest/";
-
-SimpleTest.waitForExplicitFinish();
-
-// Candidate RPs, and whether we expect them to experience an error.
-// Will will load each of these in turn into an iframe.  The candiates
-// will invoke navigator.mozId.watch().  If they do not provide the
-// correct arguments to watch(), nsDOMIdentity will throw an exception.
-let candidates = [
-  [BASE_URL + "file_browserid_rp_ok.html",          false],
-  [BASE_URL + "file_browserid_rp_noOnlogin.html",   true ],
-  [BASE_URL + "file_fxa_rp_ok.html",                false],
-  [BASE_URL + "file_fxa_rp_noOnlogin.html",         true ],
-  [BASE_URL + "file_fxa_rp_noOnlogout.html",        true ],
-  [BASE_URL + "file_fxa_rp_noOnready.html",         true ],
-];
-
-let checkedCount = 0;
-let checksTodo = candidates.length;
-
-// Each iframe will postMessage to us, telling us whether they caught
-// an exception or not when calling watch().
-window.addEventListener('message', function onMessage(event) {
-  let message = JSON.parse(event.data);
-  let [uri, expectedError] = candidates[checkedCount];
-
-  is(message.error, expectedError, "Unexpected error result from " + uri);
-
-  if (++checkedCount < checksTodo) {
-    testRunner.next();
-  } else {
-    window.removeEventListener('message', onMessage);
-    SimpleTest.finish();
-  }
-}, false);
-
-let content = document.getElementById('content');
-function runTest() {
-  for (let [uri, _] of candidates) {
-
-    let iframe = document.createElement('iframe');
-    iframe.setAttribute('mozbrowser', 'true');
-    iframe.src = uri;
-
-    content.appendChild(iframe);
-
-    yield undefined;
-  }
-}
-
-let testRunner = runTest();
-
-// Enable the identity systems and use verbose logging
-SpecialPowers.pushPrefEnv({'set': [
-    ['dom.identity.enabled', true],               // navigator.mozId
-    ['identity.fxaccounts.enabled', true],        // fx accounts
-    ['dom.identity.syntheticEventsOk', true],     // so we can call request()
-    ['toolkit.identity.debug', true],             // verbose identity logging
-    ['browser.dom.window.dump.enabled', true],
-    ["security.apps.privileged.CSP.default", "'inline-script';"],
-    ["security.apps.certified.CSP.default", "'inline-script';"],
-  ]},
-  function () { testRunner.next(); }
-);
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/identity/tests/mochitest/test_syntheticEvents.html
+++ /dev/null
@@ -1,210 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-  https://bugzilla.mozilla.org/show_bug.cgi?id=971379
--->
-<head>
-  <meta charset="utf-8">
-  <title>Certified/packaged apps may use synthetic events with FXA -- Bug 971379</title>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=971379">Mozilla Bug 971379</a>
-<p id="display"></p>
-<div id="content">
-
-</div>
-<pre id="test">
-<script type="application/javascript;version=1.8">
-
-SimpleTest.waitForExplicitFinish();
-
-Components.utils.import("resource://gre/modules/Promise.jsm");
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/DOMIdentity.jsm");
-Components.utils.import("resource://gre/modules/identity/jwcrypto.jsm");
-Components.utils.import("resource://gre/modules/identity/FirefoxAccounts.jsm");
-
-// Mock the Firefox Accounts manager to give a dummy assertion, just to confirm
-// that we're making the trip through the dom/identity and toolkit/identity
-// plumbing.
-function MockFXAManager() {}
-MockFXAManager.prototype = {
-  getAssertion: function(audience, options) {
-    if (options.silent) {
-      return Promise.resolve(null);
-    }
-    return Promise.resolve("here~you.go.dude");
-  }
-};
-
-let originalManager = FirefoxAccounts.fxAccountsManager;
-FirefoxAccounts.fxAccountsManager = new MockFXAManager();
-
-// Mock IdentityService (Persona) so we can test request() while not handling
-// user input on an installed app.  Since in this test suite, we have only this
-// one test for Persona, we additionally cause request() to throw if invoked, as
-// added security that nsDOMIdentity did not emit a request message.
-let MockIdentityService = function() {
-  this.RP = this;
-  this.contexts = {};
-}
-MockIdentityService.prototype = {
-  watch: function(context) {
-    this.contexts[context.id] = context;
-    context.doReady();
-  },
-
-  request: function(message) {
-    ok(false, "nsDOMIdentity should block Persona request() in this test suite");
-  },
-};
-DOMIdentity._mockIdentityService = new MockIdentityService();
-
-// The manifests for these apps are all declared in
-// /testing/profiles/webapps_mochitest.json.  They are injected into the profile
-// by /testing/mochitest/runtests.py with the appropriate appStatus.  So we don't
-// have to manually install any apps.
-let apps = [
-  {
-    title: "an installed app, which must request() in a native event",
-    manifest: "https://example.com/manifest.webapp",
-    origin: "https://example.com",
-    uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_syntheticEvents.html",
-    wantIssuer: "",  // default to persona
-    expected: {
-      success: false,
-      errors: [
-        "ERROR_REQUEST_WHILE_NOT_HANDLING_USER_INPUT",
-      ],
-    },
-  },
-  {
-    title: "a privileged app, which may use synthetic events",
-    manifest: "https://example.com/manifest_priv.webapp",
-    origin: "https://example.com",
-    uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_syntheticEvents.html",
-    wantIssuer: "firefox-accounts",
-    expected: {
-      success: true,
-    },
-  },
-  {
-    title: "a certified app, which may use synthetic events",
-    manifest: "https://example.com/manifest_cert.webapp",
-    origin: "https://example.com",
-    uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_syntheticEvents.html",
-    wantIssuer: "firefox-accounts",
-    expected: {
-      success: true,
-    },
-  },
-];
-
-let eventsReceived = 0;
-let testRunner = runTest();
-
-function receiveMessage(event) {
-  dump("** Received response: " + event.data + "\n");
-  let result = JSON.parse(event.data);
-  let app = apps[result.appIndex];
-  if (app.received) {
-    return;
-  }
-  apps[result.appIndex].received = true;
-
-  let expected = app.expected;
-  let receivedErrors = [];
-
-  is(result.success, expected.success,
-    "Assertion request " + (expected.success ? "succeeds" : "fails"));
-
-  if (result.error) {
-    receivedErrors.push(result.error);
-  }
-
-  ok(receivedErrors.length === (expected.errors || []).length,
-     "Received errors should be equal to expected errors");
-
-  receivedErrors.forEach((error) => {
-    ok(expected.errors.indexOf(error) > -1,
-       "Received " + error + ".  " +
-       "Expected errors are: " + JSON.stringify(expected.errors));
-  });
-
-  eventsReceived += 1;
-
-  if (eventsReceived === apps.length) {
-    window.removeEventListener("message", receiveMessage);
-
-    FirefoxAccounts.fxAccountsManager = originalManager;
-
-    SimpleTest.finish();
-
-    return;
-  }
-
-  testRunner.next();
-}
-
-window.addEventListener("message", receiveMessage, false, true);
-
-function runTest() {
-  let index;
-  for (let i = 0; i < apps.length; i++) {
-    let app = apps[i];
-    dump("** Testing " + app.title + "\n");
-
-    let iframe = document.createElement("iframe");
-
-    iframe.setAttribute("mozapp", app.manifest);
-    iframe.setAttribute("mozbrowser", "true");
-    iframe.src = app.uri;
-
-    document.getElementById("content").appendChild(iframe);
-
-    index = i;
-    (function(_index) {
-      iframe.addEventListener("load", function onLoad() {
-        iframe.removeEventListener("load", onLoad);
-
-        SpecialPowers.addPermission(
-          "firefox-accounts",
-          SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION,
-          iframe.contentDocument
-        );
-
-        // Because the <iframe mozapp> can't parent its way back to us, we
-        // provide this handle it can use to postMessage to us.
-        Components.utils.exportFunction(window.postMessage.bind(window), iframe.contentWindow, {defineAs: 'doPostMessage'});
-
-        iframe.contentWindow.postMessage({
-          wantIssuer: app.wantIssuer,
-          appIndex: _index
-        }, "*");
-      }, false);
-    })(index);
-    yield undefined;
-  }
-}
-
-SpecialPowers.pushPrefEnv({"set":
-  [
-    ["dom.mozBrowserFramesEnabled", true],
-    ["dom.identity.enabled", true],
-    ["identity.fxaccounts.enabled", true],
-    ["toolkit.identity.debug", true],
-    ["security.apps.privileged.CSP.default", "'inline-script';"],
-    ["security.apps.certified.CSP.default", "'inline-script';"],
-  ]},
-  function() {
-    testRunner.next();
-  }
-);
-
-
-</script>
-</pre>
-</body>
-</html>
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -134,17 +134,16 @@ if CONFIG['MOZ_NFC']:
     DIRS += ['nfc']
 
 if CONFIG['MOZ_SECUREELEMENT']:
     DIRS += ['secureelement']
 
 if CONFIG['MOZ_B2G']:
     DIRS += [
         'downloads',
-        'identity'
     ]
 
 DIRS += ['presentation']
 
 TEST_DIRS += [
     'tests',
     'imptests',
 ]
deleted file mode 100644
--- a/dom/webidl/Identity.webidl
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-callback IdentityOnReadyCallback = void();
-callback IdentityOnLoginCallback = void(DOMString identityAssertion);
-callback IdentityOnLogoutCallback = void();
-callback IdentityOnCancelCallback = void(DOMString? error);
-callback IdentityOnErrorCallback = void(DOMString error);
-
-dictionary IdentityWatchOptions {
-  // Required callback
-  IdentityOnLoginCallback onlogin;
-
-  // Optional parameters
-  DOMString wantIssuer;
-  DOMString loggedInUser;
-
-  // Optional callbacks
-  IdentityOnReadyCallback onready;
-  IdentityOnLogoutCallback onlogout;
-  IdentityOnErrorCallback onerror;
-
-  // Certified apps can specify this
-  DOMString audience;
-};
-
-dictionary IdentityRequestOptions {
-  // Optional parameters
-  long refreshAuthentication;
-  DOMString termsOfService;
-  DOMString privacyPolicy;
-  DOMString backgroundColor;
-  DOMString siteLogo;
-  DOMString siteName;
-  DOMString returnTo;
-
-  IdentityOnCancelCallback oncancel;
-
-  // Certified apps can specify this
-  DOMString origin;
-};
-
-dictionary IdentityGetOptions {
-  DOMString privacyPolicy;
-  DOMString termsOfService;
-  DOMString privacyURL;
-  DOMString tosURL;
-  DOMString siteName;
-  DOMString siteLogo;
-};
-
-[JSImplementation="@mozilla.org/identity/manager;1",
- NoInterfaceObject,
- NavigatorProperty="mozId",
- Pref="dom.identity.enabled"]
-interface IdentityManager {
-  void watch(optional IdentityWatchOptions options);
-  void request(optional IdentityRequestOptions options);
-  void logout();
-
-  [Pref="dom.identity.exposeLegacyGetAPI"]
-  void get(IdentityOnLoginCallback callback, optional IdentityGetOptions options);
-
-  [Pref="dom.identity.exposeLegacyGetVerifiedEmailAPI"]
-  void getVerifiedEmail(IdentityOnLoginCallback callback);
-};
-
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -900,17 +900,16 @@ if CONFIG['MOZ_BUILD_APP'] in ['browser'
 if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
     WEBIDL_FILES += [
         'External.webidl',
     ]
 
 if CONFIG['MOZ_B2G']:
     WEBIDL_FILES += [
         'Apps.webidl',
-        'Identity.webidl',
         'MozApplicationEvent.webidl'
     ]
     GENERATED_EVENTS_WEBIDL_FILES += [
         'MozApplicationEvent.webidl'
     ]
 
 if CONFIG['ACCESSIBILITY']:
     WEBIDL_FILES += [
--- a/services/fxaccounts/tests/mochitest/test_invalidEmailCase.html
+++ b/services/fxaccounts/tests/mochitest/test_invalidEmailCase.html
@@ -111,17 +111,16 @@ function runTest() {
     },
     signInError => {
       ok(false, JSON.stringify(signInError));
     }
   );
 };
 
 SpecialPowers.pushPrefEnv({"set": [
-    ["dom.identity.enabled", true],                // navigator.mozId
     ["identity.fxaccounts.enabled", true],         // fx accounts
     ["identity.fxaccounts.auth.uri", TEST_SERVER], // our sjs server
     ["toolkit.identity.debug", true],              // verbose identity logging
     ["browser.dom.window.dump.enabled", true],
   ]},
   function () { runTest(); }
 );