mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge b2g-inbound to m-c. a=merge
This commit is contained in:
commit
08cc354053
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c47094a26c87ba71a3da4bae54febd0da21f3393"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c47094a26c87ba71a3da4bae54febd0da21f3393"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c47094a26c87ba71a3da4bae54febd0da21f3393"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c47094a26c87ba71a3da4bae54febd0da21f3393"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c47094a26c87ba71a3da4bae54febd0da21f3393"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "6f63b10d567e5a8fb51bbebe5e482294427cc05d",
|
||||
"revision": "f705a3f96020c7d7aa5ec63bf3417db29e1ab2a2",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c47094a26c87ba71a3da4bae54febd0da21f3393"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c47094a26c87ba71a3da4bae54febd0da21f3393"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c47094a26c87ba71a3da4bae54febd0da21f3393"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="aebf432f334ec0b48eb358569b9dfbfbead48017"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c47094a26c87ba71a3da4bae54febd0da21f3393"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="40cac290f0a3253d31242d7f50b1d2ddd2f47cda"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="9ff55cd0aefea23e4c60e5844c155c6ebc2e632b"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -367,6 +367,17 @@ this.PermissionsTable = { geolocation: {
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write", "create"]
|
||||
},
|
||||
"firefox-accounts": {
|
||||
app: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
},
|
||||
"moz-firefox-accounts": {
|
||||
app: DENY_ACTION,
|
||||
privileged: PROMPT_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
substitute: ["firefox-accounts"]
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -145,8 +145,7 @@ public:
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(!mShuttingDownOnIOThread);
|
||||
|
||||
RemoveWatchers(READ_WATCHER | WRITE_WATCHER);
|
||||
|
||||
Close(); // will also remove fd from I/O loop
|
||||
mShuttingDownOnIOThread = true;
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,12 @@ public:
|
||||
MOZ_ASSERT(mCellBroadcast);
|
||||
mCellBroadcast = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
~Listener()
|
||||
{
|
||||
MOZ_ASSERT(!mCellBroadcast);
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(CellBroadcast::Listener, nsICellBroadcastListener)
|
||||
|
@ -21,7 +21,6 @@ public:
|
||||
NS_DECL_NSIICCLISTENER
|
||||
|
||||
IccListener(IccManager* aIccManager, uint32_t aClientId);
|
||||
~IccListener();
|
||||
|
||||
void
|
||||
Shutdown();
|
||||
@ -32,6 +31,9 @@ public:
|
||||
return mIcc;
|
||||
}
|
||||
|
||||
private:
|
||||
~IccListener();
|
||||
|
||||
private:
|
||||
uint32_t mClientId;
|
||||
// We did not setup 'mIcc' and 'mIccManager' being a participant of cycle
|
||||
|
@ -26,7 +26,6 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IccManager, DOMEventTargetHelper)
|
||||
|
||||
IccManager(nsPIDOMWindow* aWindow);
|
||||
~IccManager();
|
||||
|
||||
void
|
||||
Shutdown();
|
||||
@ -52,6 +51,9 @@ public:
|
||||
virtual JSObject*
|
||||
WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
~IccManager();
|
||||
|
||||
private:
|
||||
nsTArray<nsRefPtr<IccListener>> mIccListeners;
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ 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"];
|
||||
@ -38,6 +39,10 @@ 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));
|
||||
}
|
||||
@ -98,7 +103,7 @@ IDPAuthenticationContext.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
function RPWatchContext(aOptions, aTargetMM) {
|
||||
function RPWatchContext(aOptions, aTargetMM, aPrincipal) {
|
||||
objectCopy(aOptions, this);
|
||||
|
||||
// id and origin are required
|
||||
@ -106,6 +111,8 @@ function RPWatchContext(aOptions, aTargetMM) {
|
||||
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;
|
||||
|
||||
@ -182,8 +189,8 @@ this.DOMIdentity = {
|
||||
/*
|
||||
* Create a new RPWatchContext, and update the context maps.
|
||||
*/
|
||||
newContext: function(message, targetMM) {
|
||||
let context = new RPWatchContext(message, targetMM);
|
||||
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;
|
||||
@ -234,6 +241,28 @@ this.DOMIdentity = {
|
||||
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 secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager);
|
||||
let uri = Services.io.newURI(aMessage.principal.origin, null, null);
|
||||
let principal = secMan.getAppCodebasePrincipal(uri,
|
||||
aMessage.principal.appId, aMessage.principal.isInBrowserElement);
|
||||
|
||||
let permission =
|
||||
permissionManager.testPermissionFromPrincipal(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;
|
||||
@ -242,19 +271,23 @@ this.DOMIdentity = {
|
||||
// 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);
|
||||
this._watch(msg, targetMM, aMessage.principal);
|
||||
break;
|
||||
case "Identity:RP:Unwatch":
|
||||
this._unwatch(msg, targetMM);
|
||||
break;
|
||||
case "Identity:RP:Request":
|
||||
this._request(msg, targetMM);
|
||||
this._request(msg);
|
||||
break;
|
||||
case "Identity:RP:Logout":
|
||||
this._logout(msg, targetMM);
|
||||
this._logout(msg);
|
||||
break;
|
||||
// IDP
|
||||
case "Identity:IDP:BeginProvisioning":
|
||||
@ -328,9 +361,9 @@ this.DOMIdentity = {
|
||||
ppmm = null;
|
||||
},
|
||||
|
||||
_watch: function DOMIdentity__watch(message, targetMM) {
|
||||
log("DOMIdentity__watch: " + message.id);
|
||||
let context = this.newContext(message, targetMM);
|
||||
_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);
|
||||
},
|
||||
|
||||
|
@ -40,8 +40,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
|
||||
|
||||
const ERRORS = {
|
||||
"ERROR_NOT_AUTHORIZED_FOR_FIREFOX_ACCOUNTS":
|
||||
"Only privileged and certified apps may use Firefox Accounts",
|
||||
"ERROR_INVALID_ASSERTION_AUDIENCE":
|
||||
"Assertion audience may not differ from origin",
|
||||
"ERROR_REQUEST_WHILE_NOT_HANDLING_USER_INPUT":
|
||||
@ -150,7 +148,12 @@ nsDOMIdentity.prototype = {
|
||||
// broken client to be able to call watch() any more. It's broken.
|
||||
return;
|
||||
}
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Watch", message);
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:RP:Watch",
|
||||
message,
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
request: function nsDOMIdentity_request(aOptions = {}) {
|
||||
@ -221,7 +224,12 @@ nsDOMIdentity.prototype = {
|
||||
}
|
||||
|
||||
this._rpCalls++;
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Request", message);
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:RP:Request",
|
||||
message,
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
logout: function nsDOMIdentity_logout() {
|
||||
@ -241,7 +249,12 @@ nsDOMIdentity.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:RP:Logout", message);
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:RP:Logout",
|
||||
message,
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
/*
|
||||
@ -324,8 +337,12 @@ nsDOMIdentity.prototype = {
|
||||
}
|
||||
|
||||
this._beginProvisioningCallback = aCallback;
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:BeginProvisioning",
|
||||
this.DOMIdentityMessage());
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:IDP:BeginProvisioning",
|
||||
this.DOMIdentityMessage(),
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
genKeyPair: function nsDOMIdentity_genKeyPair(aCallback) {
|
||||
@ -341,8 +358,12 @@ nsDOMIdentity.prototype = {
|
||||
}
|
||||
|
||||
this._genKeyPairCallback = aCallback;
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:GenKeyPair",
|
||||
this.DOMIdentityMessage());
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:IDP:GenKeyPair",
|
||||
this.DOMIdentityMessage(),
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
registerCertificate: function nsDOMIdentity_registerCertificate(aCertificate) {
|
||||
@ -357,7 +378,12 @@ nsDOMIdentity.prototype = {
|
||||
|
||||
let message = this.DOMIdentityMessage();
|
||||
message.cert = aCertificate;
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:RegisterCertificate", message);
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:IDP:RegisterCertificate",
|
||||
message,
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
raiseProvisioningFailure: function nsDOMIdentity_raiseProvisioningFailure(aReason) {
|
||||
@ -372,7 +398,12 @@ nsDOMIdentity.prototype = {
|
||||
|
||||
let message = this.DOMIdentityMessage();
|
||||
message.reason = aReason;
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:ProvisioningFailure", message);
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:IDP:ProvisioningFailure",
|
||||
message,
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -392,8 +423,12 @@ nsDOMIdentity.prototype = {
|
||||
}
|
||||
|
||||
this._beginAuthenticationCallback = aCallback;
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:BeginAuthentication",
|
||||
this.DOMIdentityMessage());
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:IDP:BeginAuthentication",
|
||||
this.DOMIdentityMessage(),
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
completeAuthentication: function nsDOMIdentity_completeAuthentication() {
|
||||
@ -405,8 +440,12 @@ nsDOMIdentity.prototype = {
|
||||
}
|
||||
this._authenticationEnded = true;
|
||||
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:CompleteAuthentication",
|
||||
this.DOMIdentityMessage());
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:IDP:CompleteAuthentication",
|
||||
this.DOMIdentityMessage(),
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
raiseAuthenticationFailure: function nsDOMIdentity_raiseAuthenticationFailure(aReason) {
|
||||
@ -419,7 +458,12 @@ nsDOMIdentity.prototype = {
|
||||
|
||||
let message = this.DOMIdentityMessage();
|
||||
message.reason = aReason;
|
||||
this._identityInternal._mm.sendAsyncMessage("Identity:IDP:AuthenticationFailure", message);
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:IDP:AuthenticationFailure",
|
||||
message,
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
},
|
||||
|
||||
// Private.
|
||||
@ -510,7 +554,8 @@ nsDOMIdentity.prototype = {
|
||||
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");
|
||||
this._log("WARNING: Received OnCancel message, but there is no RP " +
|
||||
"watcher");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -520,7 +565,8 @@ nsDOMIdentity.prototype = {
|
||||
break;
|
||||
case "Identity:RP:Watch:OnError":
|
||||
if (!this._rpWatcher) {
|
||||
this._log("WARNING: Received OnError message, but there is no RP watcher");
|
||||
this._log("WARNING: Received OnError message, but there is no RP " +
|
||||
"watcher");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -593,7 +639,6 @@ nsDOMIdentity.prototype = {
|
||||
let message = {
|
||||
errors: []
|
||||
};
|
||||
let principal = Ci.nsIPrincipal;
|
||||
|
||||
objectCopy(aOptions, message);
|
||||
|
||||
@ -603,19 +648,6 @@ nsDOMIdentity.prototype = {
|
||||
// window origin
|
||||
message.origin = this._origin;
|
||||
|
||||
// On b2g, an app's status can be NOT_INSTALLED, INSTALLED, PRIVILEGED, or
|
||||
// CERTIFIED. Compare the appStatus value to the constants enumerated in
|
||||
// Ci.nsIPrincipal.APP_STATUS_*.
|
||||
message.appStatus = this._appStatus;
|
||||
|
||||
// Currently, we only permit certified and privileged apps to use
|
||||
// Firefox Accounts.
|
||||
if (aOptions.wantIssuer == "firefox-accounts" &&
|
||||
this._appStatus !== principal.APP_STATUS_PRIVILEGED &&
|
||||
this._appStatus !== principal.APP_STATUS_CERTIFIED) {
|
||||
message.errors.push("ERROR_NOT_AUTHORIZED_FOR_FIREFOX_ACCOUNTS");
|
||||
}
|
||||
|
||||
// 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
|
||||
@ -628,7 +660,7 @@ nsDOMIdentity.prototype = {
|
||||
// and then post-message the results down to their app.
|
||||
let _audience = message.origin;
|
||||
if (message.audience && message.audience != message.origin) {
|
||||
if (this._appStatus === principal.APP_STATUS_CERTIFIED) {
|
||||
if (this._appStatus === Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
|
||||
_audience = message.audience;
|
||||
this._log("Certified app setting assertion audience: " + _audience);
|
||||
} else {
|
||||
@ -648,7 +680,9 @@ nsDOMIdentity.prototype = {
|
||||
this._log("nsDOMIdentity uninit() " + this._id);
|
||||
this._identityInternal._mm.sendAsyncMessage(
|
||||
"Identity:RP:Unwatch",
|
||||
{ id: this._id }
|
||||
{ id: this._id },
|
||||
null,
|
||||
this._window.document.nodePrincipal
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -22,31 +22,49 @@
|
||||
window.realParent.postMessage(JSON.stringify(message), "*");
|
||||
}
|
||||
|
||||
function onready() {
|
||||
navigator.mozId.request();
|
||||
}
|
||||
|
||||
function onlogin(backedAssertion) {
|
||||
postResults({success: true, backedAssertion: backedAssertion});
|
||||
}
|
||||
|
||||
function onerror(error) {
|
||||
postResults({success: false, error: error});
|
||||
}
|
||||
|
||||
onmessage = function(event) {
|
||||
navigator.mozId.watch({
|
||||
wantIssuer: "firefox-accounts",
|
||||
audience: event.data.audience,
|
||||
onready: onready,
|
||||
onlogin: onlogin,
|
||||
onerror: onerror,
|
||||
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 () {},
|
||||
});
|
||||
// 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>
|
||||
|
@ -23,24 +23,34 @@
|
||||
window.realParent.postMessage(JSON.stringify(message), "*");
|
||||
}
|
||||
|
||||
function onready() {
|
||||
navigator.mozId.request();
|
||||
}
|
||||
|
||||
function onlogin(backedAssertion) {
|
||||
postResults({success: true, backedAssertion: backedAssertion});
|
||||
}
|
||||
|
||||
function onerror(error) {
|
||||
postResults({success: false, error: error});
|
||||
}
|
||||
|
||||
onmessage = function(message) {
|
||||
onmessage = function(event) {
|
||||
navigator.mozId.watch({
|
||||
wantIssuer: message.data.wantIssuer,
|
||||
onready: onready,
|
||||
onerror: onerror,
|
||||
onlogin: onlogin,
|
||||
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() {},
|
||||
});
|
||||
};
|
||||
|
@ -102,7 +102,7 @@ let apps = [
|
||||
uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_declareAudience.html",
|
||||
expected: {
|
||||
success: false,
|
||||
underprivileged: false,
|
||||
underprivileged: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -114,6 +114,7 @@ let apps = [
|
||||
uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_declareAudience.html",
|
||||
expected: {
|
||||
success: true,
|
||||
underprivileged: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -129,9 +130,7 @@ let apps = [
|
||||
},
|
||||
];
|
||||
|
||||
let appIndex = 0;
|
||||
let expectedErrors = 0;
|
||||
let receivedErrors = [];
|
||||
let eventsReceived = 0;
|
||||
let testRunner = runTest();
|
||||
|
||||
// Successful tests will send exactly one message. But for error tests, we may
|
||||
@ -139,9 +138,24 @@ let testRunner = runTest();
|
||||
// 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[appIndex];
|
||||
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");
|
||||
|
||||
@ -150,51 +164,41 @@ function receiveMessage(event) {
|
||||
let components = extractAssertionComponents(result.backedAssertion);
|
||||
is(components.payload.aud, app.wantAudience || app.origin,
|
||||
"Got desired assertion audience");
|
||||
|
||||
} else {
|
||||
receivedErrors.push(result.error);
|
||||
}
|
||||
|
||||
if (receivedErrors.length === expectedErrors) {
|
||||
|
||||
if (expected.underprivileged) {
|
||||
ok(receivedErrors.indexOf("ERROR_NOT_AUTHORIZED_FOR_FIREFOX_ACCOUNTS") > -1,
|
||||
"Expect a complaint that this app cannot use FxA.");
|
||||
}
|
||||
if (!expected.success) {
|
||||
ok(receivedErrors.indexOf("ERROR_INVALID_ASSERTION_AUDIENCE") > -1,
|
||||
"Expect an error getting an assertion");
|
||||
}
|
||||
ok(receivedErrors.length === expectedErrors,
|
||||
"Received errors should be equal to expected errors");
|
||||
|
||||
appIndex += 1;
|
||||
|
||||
if (appIndex === apps.length) {
|
||||
window.removeEventListener("message", receiveMessage);
|
||||
|
||||
FirefoxAccounts.fxAccountsManager = originalManager;
|
||||
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
testRunner.next();
|
||||
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() {
|
||||
for (let app of apps) {
|
||||
dump("** Testing " + app.title + "\n");
|
||||
// Set up state for message handler
|
||||
expectedErrors = 0;
|
||||
receivedErrors = [];
|
||||
if (!app.expected.success) {
|
||||
expectedErrors += 1;
|
||||
}
|
||||
if (app.expected.underprivileged) {
|
||||
expectedErrors += 1;
|
||||
}
|
||||
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");
|
||||
|
||||
@ -204,24 +208,35 @@ function runTest() {
|
||||
|
||||
document.getElementById("content").appendChild(iframe);
|
||||
|
||||
iframe.addEventListener("load", function onLoad() {
|
||||
iframe.removeEventListener("load", onLoad);
|
||||
index = i;
|
||||
(function(_index) {
|
||||
iframe.addEventListener("load", function onLoad() {
|
||||
iframe.removeEventListener("load", onLoad);
|
||||
|
||||
let principal = iframe.contentDocument.nodePrincipal;
|
||||
is(principal.appStatus, app.appStatus,
|
||||
"Iframe's document.nodePrincipal has expected appStatus");
|
||||
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 to our window so it can postMessage to us.
|
||||
iframe.contentWindow.wrappedJSObject.realParent = window;
|
||||
let principal = iframe.contentDocument.nodePrincipal;
|
||||
is(principal.appStatus, app.appStatus,
|
||||
"Iframe's document.nodePrincipal has expected appStatus");
|
||||
|
||||
// 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}, "*");
|
||||
}, false);
|
||||
// Because the <iframe mozapp> can't parent its way back to us, we
|
||||
// provide this handle to our window so it can postMessage to us.
|
||||
iframe.contentWindow.wrappedJSObject.realParent = window;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@ -259,9 +274,8 @@ SpecialPowers.pushPrefEnv({"set":
|
||||
["identity.fxaccounts.enabled", true],
|
||||
["toolkit.identity.debug", true],
|
||||
["dom.identity.syntheticEventsOk", true],
|
||||
|
||||
["security.apps.privileged.CSP.default", ""],
|
||||
["security.apps.certified.CSP.default", ""],
|
||||
["security.apps.privileged.CSP.default", "'inline-script';"],
|
||||
["security.apps.certified.CSP.default", "'inline-script';"],
|
||||
]},
|
||||
function() {
|
||||
testRunner.next();
|
||||
|
@ -85,6 +85,8 @@ SpecialPowers.pushPrefEnv({'set': [
|
||||
['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(); }
|
||||
);
|
||||
|
@ -80,19 +80,6 @@ let apps = [
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "an installed app, which must may not use firefox accounts",
|
||||
manifest: "https://example.com/manifest.webapp",
|
||||
origin: "https://example.com",
|
||||
uri: "https://example.com/chrome/dom/identity/tests/mochitest/file_syntheticEvents.html",
|
||||
wantIssuer: "firefox-accounts",
|
||||
expected: {
|
||||
success: false,
|
||||
errors: [
|
||||
"ERROR_NOT_AUTHORIZED_FOR_FIREFOX_ACCOUNTS",
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "a privileged app, which may use synthetic events",
|
||||
manifest: "https://example.com/manifest_priv.webapp",
|
||||
@ -115,15 +102,20 @@ let apps = [
|
||||
},
|
||||
];
|
||||
|
||||
let appIndex = 0;
|
||||
let eventsReceived = 0;
|
||||
let testRunner = runTest();
|
||||
let receivedErrors = [];
|
||||
|
||||
function receiveMessage(event) {
|
||||
dump("** Received response: " + event.data + "\n");
|
||||
let result = JSON.parse(event.data);
|
||||
let app = apps[appIndex];
|
||||
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"));
|
||||
@ -132,40 +124,38 @@ function receiveMessage(event) {
|
||||
receivedErrors.push(result.error);
|
||||
}
|
||||
|
||||
if (receivedErrors.length === (expected.errors || []).length) {
|
||||
receivedErrors.forEach((error) => {
|
||||
ok(expected.errors.indexOf(error) > -1,
|
||||
"Received " + error + ". " +
|
||||
"Expected errors are: " + JSON.stringify(expected.errors));
|
||||
});
|
||||
ok(receivedErrors.length === (expected.errors || []).length,
|
||||
"Received errors should be equal to expected errors");
|
||||
|
||||
appIndex += 1;
|
||||
receivedErrors.forEach((error) => {
|
||||
ok(expected.errors.indexOf(error) > -1,
|
||||
"Received " + error + ". " +
|
||||
"Expected errors are: " + JSON.stringify(expected.errors));
|
||||
});
|
||||
|
||||
if (appIndex === apps.length) {
|
||||
window.removeEventListener("message", receiveMessage);
|
||||
eventsReceived += 1;
|
||||
|
||||
// Remove mock from DOMIdentity
|
||||
DOMIdentity._mockIdentityService = null;
|
||||
if (eventsReceived === apps.length) {
|
||||
window.removeEventListener("message", receiveMessage);
|
||||
|
||||
// Restore original fxa manager
|
||||
FirefoxAccounts.fxAccountsManager = originalManager;
|
||||
FirefoxAccounts.fxAccountsManager = originalManager;
|
||||
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
SimpleTest.finish();
|
||||
|
||||
testRunner.next();
|
||||
return;
|
||||
}
|
||||
|
||||
testRunner.next();
|
||||
}
|
||||
|
||||
window.addEventListener("message", receiveMessage, false, true);
|
||||
|
||||
function runTest() {
|
||||
for (let app of apps) {
|
||||
let index;
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
let app = apps[i];
|
||||
dump("** Testing " + app.title + "\n");
|
||||
|
||||
receivedErrors = [];
|
||||
|
||||
let iframe = document.createElement("iframe");
|
||||
|
||||
iframe.setAttribute("mozapp", app.manifest);
|
||||
@ -174,15 +164,26 @@ function runTest() {
|
||||
|
||||
document.getElementById("content").appendChild(iframe);
|
||||
|
||||
iframe.addEventListener("load", function onLoad() {
|
||||
iframe.removeEventListener("load", onLoad);
|
||||
index = i;
|
||||
(function(_index) {
|
||||
iframe.addEventListener("load", function onLoad() {
|
||||
iframe.removeEventListener("load", onLoad);
|
||||
|
||||
// Because the <iframe mozapp> can't parent its way back to us, we
|
||||
// provide this handle to our window so it can postMessage to us.
|
||||
iframe.contentWindow.wrappedJSObject.realParent = window;
|
||||
iframe.contentWindow.postMessage({wantIssuer: app.wantIssuer}, "*");
|
||||
}, false);
|
||||
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 to our window so it can postMessage to us.
|
||||
iframe.contentWindow.wrappedJSObject.realParent = window;
|
||||
iframe.contentWindow.postMessage({
|
||||
wantIssuer: app.wantIssuer,
|
||||
appIndex: _index
|
||||
}, "*");
|
||||
}, false);
|
||||
})(index);
|
||||
yield undefined;
|
||||
}
|
||||
}
|
||||
@ -193,9 +194,8 @@ SpecialPowers.pushPrefEnv({"set":
|
||||
["dom.identity.enabled", true],
|
||||
["identity.fxaccounts.enabled", true],
|
||||
["toolkit.identity.debug", true],
|
||||
|
||||
["security.apps.privileged.CSP.default", ""],
|
||||
["security.apps.certified.CSP.default", ""],
|
||||
["security.apps.privileged.CSP.default", "'inline-script';"],
|
||||
["security.apps.certified.CSP.default", "'inline-script';"],
|
||||
]},
|
||||
function() {
|
||||
testRunner.next();
|
||||
|
@ -43,6 +43,9 @@ public:
|
||||
return mInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
~DOMMMIError() {}
|
||||
|
||||
private:
|
||||
nsString mServiceCode;
|
||||
Nullable<int16_t> mInfo;
|
||||
|
@ -78,6 +78,9 @@ public:
|
||||
return mCdmaNetworkId;
|
||||
}
|
||||
|
||||
private:
|
||||
~MobileCellInfo() {}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
int32_t mGsmLocationAreaCode;
|
||||
|
@ -62,6 +62,12 @@ public:
|
||||
MOZ_ASSERT(mMobileConnection);
|
||||
mMobileConnection = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
~Listener()
|
||||
{
|
||||
MOZ_ASSERT(!mMobileConnection);
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(MobileConnection::Listener, nsIMobileConnectionListener)
|
||||
@ -130,6 +136,11 @@ MobileConnection::Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
MobileConnection::~MobileConnection()
|
||||
{
|
||||
MOZ_ASSERT(!(mProvider || mListener || mVoice || mData));
|
||||
}
|
||||
|
||||
JSObject*
|
||||
MobileConnection::WrapObject(JSContext* aCx)
|
||||
{
|
||||
|
@ -155,6 +155,9 @@ public:
|
||||
IMPL_EVENT_HANDLER(radiostatechange)
|
||||
IMPL_EVENT_HANDLER(clirmodechange)
|
||||
|
||||
private:
|
||||
~MobileConnection();
|
||||
|
||||
private:
|
||||
uint32_t mClientId;
|
||||
nsCOMPtr<nsIMobileConnectionProvider> mProvider;
|
||||
|
@ -93,6 +93,9 @@ public:
|
||||
return mCellInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
~MobileConnectionInfo() {}
|
||||
|
||||
private:
|
||||
bool mConnected;
|
||||
bool mEmergencyCallsOnly;
|
||||
|
@ -61,6 +61,9 @@ public:
|
||||
return Nullable<MobileNetworkState>();
|
||||
}
|
||||
|
||||
private:
|
||||
~MobileNetworkInfo() {}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
nsString mShortName;
|
||||
|
@ -382,7 +382,11 @@ NetworkStatsDB.prototype = {
|
||||
debug("New stats: " + JSON.stringify(stats));
|
||||
}
|
||||
|
||||
let request = aStore.index("network").openCursor(stats.network, "prev");
|
||||
let lowerFilter = [stats.appId, stats.serviceType, stats.network, 0];
|
||||
let upperFilter = [stats.appId, stats.serviceType, stats.network, ""];
|
||||
let range = IDBKeyRange.bound(lowerFilter, upperFilter, false, false);
|
||||
|
||||
let request = aStore.openCursor(range, 'prev');
|
||||
request.onsuccess = function onsuccess(event) {
|
||||
let cursor = event.target.result;
|
||||
if (!cursor) {
|
||||
@ -401,16 +405,9 @@ NetworkStatsDB.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
let value = cursor.value;
|
||||
if (stats.appId != value.appId ||
|
||||
(stats.appId == 0 && stats.serviceType != value.serviceType)) {
|
||||
cursor.continue();
|
||||
return;
|
||||
}
|
||||
|
||||
// There are old samples
|
||||
if (DEBUG) {
|
||||
debug("Last value " + JSON.stringify(value));
|
||||
debug("Last value " + JSON.stringify(cursor.value));
|
||||
}
|
||||
|
||||
// Remove stats previous to now - VALUE_MAX_LENGTH
|
||||
|
@ -33,11 +33,23 @@ let emulator = (function() {
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
run: run,
|
||||
P2P_RE_INDEX_0 : 0,
|
||||
P2P_RE_INDEX_1 : 1,
|
||||
T1T_RE_INDEX : 2,
|
||||
T2T_RE_INDEX : 3,
|
||||
T3T_RE_INDEX : 4,
|
||||
T4T_RE_INDEX : 5
|
||||
};
|
||||
}());
|
||||
|
||||
let NCI = (function() {
|
||||
function activateRE(re) {
|
||||
let deferred = Promise.defer();
|
||||
let cmd = 'nfc nci rf_intf_activated_ntf ' + re;
|
||||
|
||||
this.run(cmd, function(result) {
|
||||
emulator.run(cmd, function(result) {
|
||||
is(result.pop(), 'OK', 'check activation of RE' + re);
|
||||
deferred.resolve();
|
||||
});
|
||||
@ -49,7 +61,7 @@ let emulator = (function() {
|
||||
let deferred = Promise.defer();
|
||||
let cmd = 'nfc nci rf_intf_deactivate_ntf';
|
||||
|
||||
this.run(cmd, function(result) {
|
||||
emulator.run(cmd, function(result) {
|
||||
is(result.pop(), 'OK', 'check deactivate');
|
||||
deferred.resolve();
|
||||
});
|
||||
@ -61,7 +73,7 @@ let emulator = (function() {
|
||||
let deferred = Promise.defer();
|
||||
let cmd = 'nfc nci rf_discover_ntf ' + re + ' ' + type;
|
||||
|
||||
this.run(cmd, function(result) {
|
||||
emulator.run(cmd, function(result) {
|
||||
is(result.pop(), 'OK', 'check discovery of RE' + re);
|
||||
deferred.resolve();
|
||||
});
|
||||
@ -69,12 +81,23 @@ let emulator = (function() {
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
function setTagData(re, flag, tnf, type, payload) {
|
||||
return {
|
||||
activateRE: activateRE,
|
||||
deactivate: deactivate,
|
||||
notifyDiscoverRE: notifyDiscoverRE,
|
||||
LAST_NOTIFICATION: 0,
|
||||
LIMIT_NOTIFICATION: 1,
|
||||
MORE_NOTIFICATIONS: 2
|
||||
};
|
||||
}());
|
||||
|
||||
let TAG = (function() {
|
||||
function setData(re, flag, tnf, type, payload) {
|
||||
let deferred = Promise.defer();
|
||||
let cmd = "nfc tag set " + re +
|
||||
" [" + flag + "," + tnf + "," + type + "," + payload + ",]";
|
||||
|
||||
this.run(cmd, function(result) {
|
||||
emulator.run(cmd, function(result) {
|
||||
is(result.pop(), "OK", "set NDEF data of tag" + re);
|
||||
deferred.resolve();
|
||||
});
|
||||
@ -82,24 +105,31 @@ let emulator = (function() {
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
function clearTagData(re) {
|
||||
function clearData(re) {
|
||||
let deferred = Promise.defer();
|
||||
let cmd = "nfc tag clear " + re;
|
||||
|
||||
this.run(cmd, function(result) {
|
||||
emulator.run(cmd, function(result) {
|
||||
is(result.pop(), "OK", "clear tag" + re);
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
|
||||
function snepPutNdef(dsap, ssap, flags, tnf, type, payload, id) {
|
||||
return {
|
||||
setData: setData,
|
||||
clearData: clearData
|
||||
};
|
||||
}());
|
||||
|
||||
let SNEP = (function() {
|
||||
function put(dsap, ssap, flags, tnf, type, payload, id) {
|
||||
let deferred = Promise.defer();
|
||||
let cmd = "nfc snep put " + dsap + " " + ssap + " [" + flags + "," +
|
||||
tnf + "," +
|
||||
type + "," +
|
||||
payload + "," +
|
||||
id + "]";
|
||||
this.run(cmd, function(result) {
|
||||
emulator.run(cmd, function(result) {
|
||||
is(result.pop(), "OK", "send SNEP PUT");
|
||||
deferred.resolve();
|
||||
});
|
||||
@ -108,13 +138,8 @@ let emulator = (function() {
|
||||
};
|
||||
|
||||
return {
|
||||
run: run,
|
||||
activateRE: activateRE,
|
||||
deactivate: deactivate,
|
||||
notifyDiscoverRE: notifyDiscoverRE,
|
||||
setTagData: setTagData,
|
||||
clearTagData: clearTagData,
|
||||
snepPutNdef: snepPutNdef
|
||||
put: put,
|
||||
SAP_NDEF: 4
|
||||
};
|
||||
}());
|
||||
|
||||
@ -152,18 +177,6 @@ function clearPendingMessages(type) {
|
||||
});
|
||||
}
|
||||
|
||||
function enableRE0() {
|
||||
let deferred = Promise.defer();
|
||||
let cmd = 'nfc nci rf_intf_activated_ntf 0';
|
||||
|
||||
emulator.run(cmd, function(result) {
|
||||
is(result.pop(), 'OK', 'check activation of RE0');
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
log('Cleaning up');
|
||||
waitFor(function() {
|
||||
|
@ -4,7 +4,7 @@
|
||||
'use strict';
|
||||
|
||||
/* globals log, is, ok, runTests, toggleNFC, runNextTest,
|
||||
SpecialPowers, nfc, enableRE0 */
|
||||
SpecialPowers, nfc */
|
||||
|
||||
const MARIONETTE_TIMEOUT = 30000;
|
||||
const MARIONETTE_HEAD_JS = 'head.js';
|
||||
@ -50,7 +50,7 @@ function testWithTargetNoSessionToken() {
|
||||
function testWithSessionTokenWithTarget() {
|
||||
log('testWithSessionTokenWithTarget');
|
||||
toggleNFC(true)
|
||||
.then(enableRE0)
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerOnpeerready)
|
||||
.then(() => fireCheckP2PReg(MANIFEST_URL))
|
||||
.then((result) => {
|
||||
@ -69,7 +69,7 @@ function testWithSessionTokenWithTarget() {
|
||||
function testWithSessionTokenNoTarget() {
|
||||
log('testWithSessionTokenNoTarget');
|
||||
toggleNFC(true)
|
||||
.then(enableRE0)
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(() => fireCheckP2PReg(MANIFEST_URL))
|
||||
.then((result) => {
|
||||
is(result, false,
|
||||
@ -87,7 +87,7 @@ function testWithSessionTokenNoTarget() {
|
||||
function testWithSessionTokenWrongTarget() {
|
||||
log('testWithSessionTokenWrongTarget');
|
||||
toggleNFC(true)
|
||||
.then(enableRE0)
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerOnpeerready)
|
||||
.then(() => fireCheckP2PReg(FAKE_MANIFEST_URL))
|
||||
.then((result) => {
|
||||
|
@ -27,7 +27,7 @@ let sessionTokens = [];
|
||||
function testNfcNotEnabledError() {
|
||||
log('testNfcNotEnabledError');
|
||||
toggleNFC(true)
|
||||
.then(() => emulator.activateRE(0))
|
||||
.then(() => emulator.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerAndFireOnpeerready)
|
||||
.then(() => toggleNFC(false))
|
||||
.then(() => sendNDEFExpectError(nfcPeers[0], 'NfcNotEnabledError'))
|
||||
@ -45,10 +45,10 @@ function testNfcNotEnabledError() {
|
||||
function testNfcBadSessionIdError() {
|
||||
log('testNfcBadSessionIdError');
|
||||
toggleNFC(true)
|
||||
.then(() => emulator.activateRE(0))
|
||||
.then(() => emulator.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerAndFireOnpeerready)
|
||||
.then(() => emulator.deactivate())
|
||||
.then(() => emulator.activateRE(0))
|
||||
.then(() => emulator.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerAndFireOnpeerready)
|
||||
// we have 2 peers in nfcPeers array, peer0 has old/invalid session token
|
||||
.then(() => sendNDEFExpectError(nfcPeers[0], 'NfcBadSessionIdError'))
|
||||
@ -65,7 +65,7 @@ function testNfcBadSessionIdError() {
|
||||
function testNfcConnectError() {
|
||||
log('testNfcConnectError');
|
||||
toggleNFC(true)
|
||||
.then(() => emulator.activateRE(0))
|
||||
.then(() => emulator.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(registerAndFireOnpeerready)
|
||||
.then(() => connectToNFCTagExpectError(sessionTokens[0],
|
||||
'NDEF',
|
||||
@ -83,7 +83,7 @@ function testNfcConnectError() {
|
||||
function testNoErrorInTechMsg() {
|
||||
log('testNoErrorInTechMsg');
|
||||
toggleNFC(true)
|
||||
.then(() => emulator.activateRE(0))
|
||||
.then(() => emulator.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(setTechDiscoveredHandler)
|
||||
.then(setAndFireTechLostHandler)
|
||||
.then(() => toggleNFC(false))
|
||||
|
@ -4,11 +4,6 @@
|
||||
MARIONETTE_TIMEOUT = 30000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
// See nfc-nci.h.
|
||||
const NCI_LAST_NOTIFICATION = 0;
|
||||
const NCI_LIMIT_NOTIFICATION = 1;
|
||||
const NCI_MORE_NOTIFICATIONS = 2;
|
||||
|
||||
function handleTechnologyDiscoveredRE0(msg) {
|
||||
log('Received \'nfc-manager-tech-discovered\'');
|
||||
is(msg.type, 'techDiscovered', 'check for correct message type');
|
||||
@ -21,7 +16,7 @@ function testActivateRE0() {
|
||||
window.navigator.mozSetMessageHandler(
|
||||
'nfc-manager-tech-discovered', handleTechnologyDiscoveredRE0);
|
||||
|
||||
toggleNFC(true).then(() => emulator.activateRE(0));
|
||||
toggleNFC(true).then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
|
||||
}
|
||||
|
||||
// Check NCI Spec 5.2, this will change NCI state from
|
||||
@ -32,9 +27,9 @@ function testRfDiscover() {
|
||||
'nfc-manager-tech-discovered', handleTechnologyDiscoveredRE0);
|
||||
|
||||
toggleNFC(true)
|
||||
.then(() => emulator.notifyDiscoverRE(0, NCI_MORE_NOTIFICATIONS))
|
||||
.then(() => emulator.notifyDiscoverRE(1, NCI_LAST_NOTIFICATION))
|
||||
.then(() => emulator.activateRE(0));
|
||||
.then(() => NCI.notifyDiscoverRE(emulator.P2P_RE_INDEX_0, NCI.MORE_NOTIFICATIONS))
|
||||
.then(() => NCI.notifyDiscoverRE(emulator.P2P_RE_INDEX_1, NCI.LAST_NOTIFICATION))
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
|
||||
}
|
||||
|
||||
let tests = [
|
||||
|
@ -11,11 +11,6 @@ let id = "";
|
||||
|
||||
let ndef = null;
|
||||
|
||||
// See nfc-nci.h.
|
||||
const NCI_LAST_NOTIFICATION = 0;
|
||||
const NCI_LIMIT_NOTIFICATION = 1;
|
||||
const NCI_MORE_NOTIFICATIONS = 2;
|
||||
|
||||
function handleTechnologyDiscoveredRE0(msg) {
|
||||
log("Received 'nfc-manager-tech-discovered'");
|
||||
is(msg.type, "techDiscovered", "check for correct message type");
|
||||
@ -38,9 +33,9 @@ function testReceiveNDEF() {
|
||||
window.navigator.mozSetMessageHandler(
|
||||
"nfc-manager-tech-discovered", handleTechnologyDiscoveredRE0);
|
||||
toggleNFC(true)
|
||||
.then(() => emulator.activateRE(0))
|
||||
.then(() => emulator.snepPutNdef(4, 4, 0, tnf, btoa(type),
|
||||
btoa(payload), btoa(id)));
|
||||
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
|
||||
.then(() => SNEP.put(SNEP.SAP_NDEF, SNEP.SAP_NDEF, 0, tnf, btoa(type),
|
||||
btoa(payload), btoa(id)));
|
||||
}
|
||||
|
||||
let tests = [
|
||||
|
@ -16,7 +16,7 @@ function handleTechnologyDiscoveredRE0(msg) {
|
||||
is(msg.type, 'techDiscovered', 'check for correct message type');
|
||||
is(msg.techList[0], 'P2P', 'check for correct tech type');
|
||||
|
||||
emulator.deactivate();
|
||||
NCI.deactivate();
|
||||
}
|
||||
|
||||
function testTechLost() {
|
||||
@ -26,7 +26,7 @@ function testTechLost() {
|
||||
window.navigator.mozSetMessageHandler(
|
||||
'nfc-manager-tech-lost', handleTechnologyLost);
|
||||
|
||||
toggleNFC(true).then(() => emulator.activateRE(0));
|
||||
toggleNFC(true).then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
|
||||
}
|
||||
|
||||
let tests = [
|
||||
|
@ -14,7 +14,7 @@ function peerReadyCb(evt) {
|
||||
|
||||
// reset callback.
|
||||
nfc.onpeerready = null;
|
||||
emulator.deactivate();
|
||||
NCI.deactivate();
|
||||
}
|
||||
|
||||
function peerLostCb() {
|
||||
@ -71,14 +71,14 @@ function testPeerReady() {
|
||||
window.navigator.mozSetMessageHandler(
|
||||
"nfc-manager-tech-discovered", handleTechnologyDiscoveredRE0);
|
||||
|
||||
toggleNFC(true).then(() => emulator.activateRE(0));
|
||||
toggleNFC(true).then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
|
||||
}
|
||||
|
||||
function testCheckP2PRegFailure() {
|
||||
window.navigator.mozSetMessageHandler(
|
||||
"nfc-manager-tech-discovered", handleTechnologyDiscoveredRE0ForP2PRegFailure);
|
||||
|
||||
toggleNFC(true).then(() => emulator.activateRE(0));
|
||||
toggleNFC(true).then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
|
||||
}
|
||||
|
||||
function testCheckNfcPeerObjForInvalidToken() {
|
||||
|
@ -44,7 +44,7 @@ function testOnPeerReadyRE0() {
|
||||
log("Running \'testOnPeerReadyRE0\'");
|
||||
window.navigator.mozSetMessageHandler(
|
||||
"nfc-manager-tech-discovered", handleTechnologyDiscoveredRE0);
|
||||
toggleNFC(true).then(enableRE0);
|
||||
toggleNFC(true).then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
|
||||
}
|
||||
|
||||
let tests = [
|
||||
|
@ -6,11 +6,6 @@ MARIONETTE_HEAD_JS = "head.js";
|
||||
|
||||
let url = "http://www.mozilla.org";
|
||||
|
||||
const T1T_RE_INDEX = 2;
|
||||
const T2T_RE_INDEX = 3;
|
||||
const T3T_RE_INDEX = 4;
|
||||
const T4T_RE_INDEX = 5;
|
||||
|
||||
function testUrlTagDiscover(re) {
|
||||
log("Running \'testUrlTagDiscover\'");
|
||||
// TODO : Make flag value readable.
|
||||
@ -36,8 +31,8 @@ function testUrlTagDiscover(re) {
|
||||
});
|
||||
|
||||
toggleNFC(true)
|
||||
.then(() => emulator.setTagData(re, flag, tnf, btoa(type), btoa(payload)))
|
||||
.then(() => emulator.activateRE(re));
|
||||
.then(() => TAG.setData(re, flag, tnf, btoa(type), btoa(payload)))
|
||||
.then(() => NCI.activateRE(re));
|
||||
}
|
||||
|
||||
function testEmptyTagDiscover(re) {
|
||||
@ -56,40 +51,40 @@ function testEmptyTagDiscover(re) {
|
||||
});
|
||||
|
||||
toggleNFC(true)
|
||||
.then(() => emulator.clearTagData(re))
|
||||
.then(() => emulator.activateRE(re));
|
||||
.then(() => TAG.clearData(re))
|
||||
.then(() => NCI.activateRE(re));
|
||||
}
|
||||
|
||||
function testUrlT1TDiscover() {
|
||||
testUrlTagDiscover(T1T_RE_INDEX);
|
||||
testUrlTagDiscover(emulator.T1T_RE_INDEX);
|
||||
}
|
||||
|
||||
function testUrlT2TDiscover() {
|
||||
testUrlTagDiscover(T2T_RE_INDEX);
|
||||
testUrlTagDiscover(emulator.T2T_RE_INDEX);
|
||||
}
|
||||
|
||||
function testUrlT3TDiscover() {
|
||||
testUrlTagDiscover(T3T_RE_INDEX);
|
||||
testUrlTagDiscover(emulator.T3T_RE_INDEX);
|
||||
}
|
||||
|
||||
function testUrlT4TDiscover() {
|
||||
testUrlTagDiscover(T4T_RE_INDEX);
|
||||
testUrlTagDiscover(emulator.T4T_RE_INDEX);
|
||||
}
|
||||
|
||||
function testEmptyT1TDiscover() {
|
||||
testEmptyTagDiscover(T1T_RE_INDEX);
|
||||
testEmptyTagDiscover(emulator.T1T_RE_INDEX);
|
||||
}
|
||||
|
||||
function testEmptyT2TDiscover() {
|
||||
testEmptyTagDiscover(T2T_RE_INDEX);
|
||||
testEmptyTagDiscover(emulator.T2T_RE_INDEX);
|
||||
}
|
||||
|
||||
function testEmptyT3TDiscover() {
|
||||
testEmptyTagDiscover(T3T_RE_INDEX);
|
||||
testEmptyTagDiscover(emulator.T3T_RE_INDEX);
|
||||
}
|
||||
|
||||
function testEmptyT4TDiscover() {
|
||||
testEmptyTagDiscover(T4T_RE_INDEX);
|
||||
testEmptyTagDiscover(emulator.T4T_RE_INDEX);
|
||||
}
|
||||
|
||||
let tests = [
|
||||
|
@ -39,6 +39,12 @@ public:
|
||||
MOZ_ASSERT(mVoicemail);
|
||||
mVoicemail = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
~Listener()
|
||||
{
|
||||
MOZ_ASSERT(!mVoicemail);
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(Voicemail::Listener, nsIVoicemailListener)
|
||||
|
@ -60,6 +60,8 @@ XPCOMUtils.defineLazyGetter(this, 'logPII', function() {
|
||||
}
|
||||
});
|
||||
|
||||
this.FXACCOUNTS_PERMISSION = "firefox-accounts";
|
||||
|
||||
this.DATA_FORMAT_VERSION = 1;
|
||||
this.DEFAULT_STORAGE_FILENAME = "signedInUser.json";
|
||||
|
||||
@ -141,6 +143,7 @@ this.ERROR_NO_TOKEN_SESSION = "NO_TOKEN_SESSION";
|
||||
this.ERROR_NO_SILENT_REFRESH_AUTH = "NO_SILENT_REFRESH_AUTH";
|
||||
this.ERROR_NOT_VALID_JSON_BODY = "NOT_VALID_JSON_BODY";
|
||||
this.ERROR_OFFLINE = "OFFLINE";
|
||||
this.ERROR_PERMISSION_DENIED = "PERMISSION_DENIED";
|
||||
this.ERROR_REQUEST_BODY_TOO_LARGE = "REQUEST_BODY_TOO_LARGE";
|
||||
this.ERROR_SERVER_ERROR = "SERVER_ERROR";
|
||||
this.ERROR_TOO_MANY_CLIENT_REQUESTS = "TOO_MANY_CLIENT_REQUESTS";
|
||||
|
@ -21,6 +21,10 @@ Cu.import("resource://gre/modules/FxAccounts.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/FxAccountsCommon.js");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "permissionManager",
|
||||
"@mozilla.org/permissionmanager;1",
|
||||
"nsIPermissionManager");
|
||||
|
||||
this.FxAccountsManager = {
|
||||
|
||||
init: function() {
|
||||
@ -175,7 +179,7 @@ this.FxAccountsManager = {
|
||||
* FxAccountsClient.signCertificate()
|
||||
* See the latter method for possible (error code, errno) pairs.
|
||||
*/
|
||||
_handleGetAssertionError: function(reason, aAudience) {
|
||||
_handleGetAssertionError: function(reason, aAudience, aPrincipal) {
|
||||
let errno = (reason ? reason.errno : NaN) || NaN;
|
||||
// If the previously valid email/password pair is no longer valid ...
|
||||
if (errno == ERRNO_INVALID_AUTH_TOKEN) {
|
||||
@ -186,34 +190,42 @@ this.FxAccountsManager = {
|
||||
if (exists) {
|
||||
return this.getAccount().then(
|
||||
(user) => {
|
||||
return this._refreshAuthentication(aAudience, user.email, true);
|
||||
}
|
||||
);
|
||||
// ... otherwise, the account was deleted, so ask for Sign In/Up
|
||||
} else {
|
||||
return this._localSignOut().then(
|
||||
() => {
|
||||
return this._uiRequest(UI_REQUEST_SIGN_IN_FLOW, aAudience);
|
||||
},
|
||||
(reason) => { // reject primary problem, not signout failure
|
||||
log.error("Signing out in response to server error threw: " + reason);
|
||||
return this._error(reason);
|
||||
return this._refreshAuthentication(aAudience, user.email,
|
||||
aPrincipal,
|
||||
true /* logoutOnFailure */);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Otherwise, the account was deleted, so ask for Sign In/Up
|
||||
return this._localSignOut().then(
|
||||
() => {
|
||||
return this._uiRequest(UI_REQUEST_SIGN_IN_FLOW, aAudience,
|
||||
aPrincipal);
|
||||
},
|
||||
(reason) => {
|
||||
// reject primary problem, not signout failure
|
||||
log.error("Signing out in response to server error threw: " +
|
||||
reason);
|
||||
return this._error(reason);
|
||||
}
|
||||
);
|
||||
}
|
||||
return Promise.reject(reason);
|
||||
},
|
||||
|
||||
_getAssertion: function(aAudience) {
|
||||
_getAssertion: function(aAudience, aPrincipal) {
|
||||
return this._fxAccounts.getAssertion(aAudience).then(
|
||||
(result) => {
|
||||
if (aPrincipal) {
|
||||
this._addPermission(aPrincipal);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
(reason) => {
|
||||
return this._handleGetAssertionError(reason, aAudience);
|
||||
return this._handleGetAssertionError(reason, aAudience, aPrincipal);
|
||||
}
|
||||
);
|
||||
},
|
||||
@ -228,10 +240,11 @@ this.FxAccountsManager = {
|
||||
* 2) The person typing can't prove knowledge of the password used
|
||||
* to log in. Failure should do nothing.
|
||||
*/
|
||||
_refreshAuthentication: function(aAudience, aEmail, logoutOnFailure=false) {
|
||||
_refreshAuthentication: function(aAudience, aEmail, aPrincipal,
|
||||
logoutOnFailure=false) {
|
||||
this._refreshing = true;
|
||||
return this._uiRequest(UI_REQUEST_REFRESH_AUTH,
|
||||
aAudience, aEmail).then(
|
||||
aAudience, aPrincipal, aEmail).then(
|
||||
(assertion) => {
|
||||
this._refreshing = false;
|
||||
return assertion;
|
||||
@ -293,7 +306,7 @@ this.FxAccountsManager = {
|
||||
);
|
||||
},
|
||||
|
||||
_uiRequest: function(aRequest, aAudience, aParams) {
|
||||
_uiRequest: function(aRequest, aAudience, aPrincipal, aParams) {
|
||||
let ui = Cc["@mozilla.org/fxaccounts/fxaccounts-ui-glue;1"]
|
||||
.createInstance(Ci.nsIFxAccountsUIGlue);
|
||||
if (!ui[aRequest]) {
|
||||
@ -309,7 +322,7 @@ this.FxAccountsManager = {
|
||||
// Even if we get a successful result from the UI, the account will
|
||||
// most likely be unverified, so we cannot get an assertion.
|
||||
if (result && result.verified) {
|
||||
return this._getAssertion(aAudience);
|
||||
return this._getAssertion(aAudience, aPrincipal);
|
||||
}
|
||||
|
||||
return this._error(ERROR_UNVERIFIED_ACCOUNT, {
|
||||
@ -322,6 +335,17 @@ this.FxAccountsManager = {
|
||||
);
|
||||
},
|
||||
|
||||
_addPermission: function(aPrincipal) {
|
||||
// This will fail from tests cause we are running them in the child
|
||||
// process until we have chrome tests in b2g. Bug 797164.
|
||||
try {
|
||||
permissionManager.addFromPrincipal(aPrincipal, FXACCOUNTS_PERMISSION,
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
} catch (e) {
|
||||
log.warn("Could not add permission " + e);
|
||||
}
|
||||
},
|
||||
|
||||
// -- API --
|
||||
|
||||
signIn: function(aEmail, aPassword) {
|
||||
@ -469,22 +493,31 @@ this.FxAccountsManager = {
|
||||
* trigger the sign in flow.
|
||||
* else if we were asked to refresh and the grace period is up:
|
||||
* trigger the refresh flow.
|
||||
* else ask the core code for an assertion, which might itself
|
||||
* trigger either the sign in or refresh flows (if our account
|
||||
* changed on the server).
|
||||
* else:
|
||||
* request user permission to share an assertion if we don't have it
|
||||
* already and ask the core code for an assertion, which might itself
|
||||
* trigger either the sign in or refresh flows (if our account
|
||||
* changed on the server).
|
||||
*
|
||||
* aOptions can include:
|
||||
* refreshAuthentication - (bool) Force re-auth.
|
||||
* silent - (bool) Prevent any UI interaction.
|
||||
* I.e., try to get an automatic assertion.
|
||||
*/
|
||||
getAssertion: function(aAudience, aOptions) {
|
||||
getAssertion: function(aAudience, aPrincipal, aOptions) {
|
||||
if (!aAudience) {
|
||||
return this._error(ERROR_INVALID_AUDIENCE);
|
||||
}
|
||||
if (Services.io.offline) {
|
||||
return this._error(ERROR_OFFLINE);
|
||||
}
|
||||
|
||||
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager);
|
||||
let uri = Services.io.newURI(aPrincipal.origin, null, null);
|
||||
let principal = secMan.getAppCodebasePrincipal(uri,
|
||||
aPrincipal.appId, aPrincipal.isInBrowserElement);
|
||||
|
||||
return this.getAccount().then(
|
||||
user => {
|
||||
if (user) {
|
||||
@ -506,21 +539,42 @@ this.FxAccountsManager = {
|
||||
if (aOptions.silent) {
|
||||
return this._error(ERROR_NO_SILENT_REFRESH_AUTH);
|
||||
}
|
||||
let secondsSinceAuth = (Date.now() / 1000) - this._activeSession.authAt;
|
||||
let secondsSinceAuth = (Date.now() / 1000) -
|
||||
this._activeSession.authAt;
|
||||
if (secondsSinceAuth > gracePeriod) {
|
||||
return this._refreshAuthentication(aAudience, user.email);
|
||||
return this._refreshAuthentication(aAudience, user.email,
|
||||
principal,
|
||||
false /* logoutOnFailure */);
|
||||
}
|
||||
}
|
||||
// Third case: we are all set *locally*. Probably we just return
|
||||
// the assertion, but the attempt might lead to the server saying
|
||||
// we are deleted or have a new password, which will trigger a flow.
|
||||
return this._getAssertion(aAudience);
|
||||
// Also we need to check if we have permission to get the assertion,
|
||||
// otherwise we need to show the forceAuth UI to let the user know
|
||||
// that the RP with no fxa permissions is trying to obtain an
|
||||
// assertion. Once the user authenticates herself in the forceAuth UI
|
||||
// the permission will be remembered by default.
|
||||
let permission = permissionManager.testPermissionFromPrincipal(
|
||||
principal,
|
||||
FXACCOUNTS_PERMISSION
|
||||
);
|
||||
if (permission == Ci.nsIPermissionManager.PROMPT_ACTION &&
|
||||
!this._refreshing) {
|
||||
return this._refreshAuthentication(aAudience, user.email,
|
||||
principal,
|
||||
false /* logoutOnFailure */);
|
||||
} else if (permission == Ci.nsIPermissionManager.DENY_ACTION &&
|
||||
!this._refreshing) {
|
||||
return this._error(ERROR_PERMISSION_DENIED);
|
||||
}
|
||||
return this._getAssertion(aAudience, principal);
|
||||
}
|
||||
log.debug("No signed in user");
|
||||
if (aOptions && aOptions.silent) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
return this._uiRequest(UI_REQUEST_SIGN_IN_FLOW, aAudience);
|
||||
return this._uiRequest(UI_REQUEST_SIGN_IN_FLOW, aAudience, principal);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -293,6 +293,7 @@ this.MobileIdentityManager = {
|
||||
},
|
||||
|
||||
getCertificate: function(aSessionToken, aPublicKey) {
|
||||
log.debug("getCertificate");
|
||||
if (this.certificates[aSessionToken] &&
|
||||
this.certificates[aSessionToken].validUntil > this.client.hawk.now()) {
|
||||
return Promise.resolve(this.certificates[aSessionToken].cert);
|
||||
@ -308,6 +309,7 @@ this.MobileIdentityManager = {
|
||||
aPublicKey)
|
||||
.then(
|
||||
(signedCert) => {
|
||||
log.debug("Got signed certificate");
|
||||
this.certificates[aSessionToken] = {
|
||||
cert: signedCert.cert,
|
||||
validUntil: validUntil
|
||||
@ -357,6 +359,25 @@ this.MobileIdentityManager = {
|
||||
this.doVerification();
|
||||
},
|
||||
|
||||
/*********************************************************
|
||||
* Result helpers
|
||||
*********************************************************/
|
||||
success: function(aPromiseId, aResult) {
|
||||
let mm = this.messageManagers[aPromiseId];
|
||||
mm.sendAsyncMessage("MobileId:GetAssertion:Return:OK", {
|
||||
promiseId: aPromiseId,
|
||||
result: aResult
|
||||
});
|
||||
},
|
||||
|
||||
error: function(aPromiseId, aError) {
|
||||
let mm = this.messageManagers[aPromiseId];
|
||||
mm.sendAsyncMessage("MobileId:GetAssertion:Return:KO", {
|
||||
promiseId: aPromiseId,
|
||||
error: aError
|
||||
});
|
||||
},
|
||||
|
||||
/*********************************************************
|
||||
* Permissions helper
|
||||
********************************************************/
|
||||
@ -565,6 +586,7 @@ this.MobileIdentityManager = {
|
||||
return this.ui.startFlow(aManifestURL, phoneInfoArray)
|
||||
.then(
|
||||
(result) => {
|
||||
log.debug("startFlow result ${} ", result);
|
||||
if (!result ||
|
||||
(!result.phoneNumber && (result.serviceId === undefined))) {
|
||||
return Promise.reject(ERROR_INTERNAL_INVALID_PROMPT_RESULT);
|
||||
@ -576,7 +598,9 @@ this.MobileIdentityManager = {
|
||||
// If the user selected one of the existing SIM cards we have to check
|
||||
// that we either have the MSISDN for that SIM or we can do a silent
|
||||
// verification that does not require us to have the MSISDN in advance.
|
||||
if (result.serviceId !== undefined) {
|
||||
// result.serviceId can be "0".
|
||||
if (result.serviceId !== undefined &&
|
||||
result.serviceId !== null) {
|
||||
let icc = this.iccInfo[result.serviceId];
|
||||
log.debug("icc ${}", icc);
|
||||
if (!icc || !icc.msisdn && !icc.canDoSilentVerification) {
|
||||
@ -774,9 +798,22 @@ this.MobileIdentityManager = {
|
||||
|
||||
let uri = Services.io.newURI(aPrincipal.origin, null, null);
|
||||
let principal = securityManager.getAppCodebasePrincipal(
|
||||
uri, aPrincipal.appid, aPrincipal.isInBrowserElement);
|
||||
uri, aPrincipal.appId, aPrincipal.isInBrowserElement);
|
||||
let manifestURL = appsService.getManifestURLByLocalId(aPrincipal.appId);
|
||||
|
||||
let permission = permissionManager.testPermissionFromPrincipal(
|
||||
principal,
|
||||
MOBILEID_PERM
|
||||
);
|
||||
|
||||
if (permission == Ci.nsIPermissionManager.DENY_ACTION ||
|
||||
permission == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
|
||||
this.error(aPromiseId, ERROR_PERMISSION_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
let _creds;
|
||||
|
||||
// First of all we look if we already have credentials for this origin.
|
||||
// If we don't have credentials it means that it is the first time that
|
||||
// the caller requested an assertion.
|
||||
@ -790,9 +827,11 @@ this.MobileIdentityManager = {
|
||||
return;
|
||||
}
|
||||
|
||||
_creds = creds;
|
||||
|
||||
// Even if we already have credentials for this origin, the consumer
|
||||
// of the API might want to force the identity selection dialog.
|
||||
if (aOptions.forceSelection) {
|
||||
if (aOptions.forceSelection || aOptions.refreshCredentials) {
|
||||
return this.promptAndVerify(principal, manifestURL, creds)
|
||||
.then(
|
||||
(newCreds) => {
|
||||
@ -855,15 +894,8 @@ this.MobileIdentityManager = {
|
||||
// If we've just prompted the user in the previous step, the permission
|
||||
// is already granted and stored so we just progress the credentials.
|
||||
if (creds) {
|
||||
let permission = permissionManager.testPermissionFromPrincipal(
|
||||
principal,
|
||||
MOBILEID_PERM
|
||||
);
|
||||
if (permission == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||
return creds;
|
||||
} else if (permission == Ci.nsIPermissionManager.DENY_ACTION ||
|
||||
permission == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
|
||||
return Promise.reject(ERROR_PERMISSION_DENIED);
|
||||
}
|
||||
return this.promptAndVerify(principal, manifestURL, creds);
|
||||
}
|
||||
@ -901,25 +933,31 @@ this.MobileIdentityManager = {
|
||||
|
||||
this.ui.verified(decodedPayload.verifiedMSISDN);
|
||||
|
||||
let mm = this.messageManagers[aPromiseId];
|
||||
mm.sendAsyncMessage("MobileId:GetAssertion:Return:OK", {
|
||||
promiseId: aPromiseId,
|
||||
result: assertion
|
||||
});
|
||||
this.success(aPromiseId, assertion);
|
||||
}
|
||||
)
|
||||
.then(
|
||||
null,
|
||||
(error) => {
|
||||
log.error("getMobileIdAssertion rejected with " + error);
|
||||
log.error("getMobileIdAssertion rejected with ${}", error);
|
||||
|
||||
// If we got an invalid token error means that the credentials that
|
||||
// we have are not valid anymore and so we need to refresh them. We
|
||||
// do that removing the stored credentials and starting over. We also
|
||||
// make sure that we do this only once.
|
||||
if (error === ERROR_INVALID_AUTH_TOKEN &&
|
||||
!aOptions.refreshCredentials) {
|
||||
log.debug("Need to get new credentials");
|
||||
aOptions.refreshCredentials = true;
|
||||
_creds && this.credStore.delete(_creds.msisdn);
|
||||
this.getMobileIdAssertion(aPrincipal, aPromiseId, aOptions);
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify the error to the UI.
|
||||
this.ui.error(error);
|
||||
|
||||
let mm = this.messageManagers[aPromiseId];
|
||||
mm.sendAsyncMessage("MobileId:GetAssertion:Return:KO", {
|
||||
promiseId: aPromiseId,
|
||||
error: error
|
||||
});
|
||||
this.error(aPromiseId, error);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
@ -29,9 +29,10 @@ const GET_ASSERTION_RETURN_KO = "MobileId:GetAssertion:Return:KO";
|
||||
// === Globals ===
|
||||
|
||||
const ORIGIN = "app://afakeorigin";
|
||||
const APP_ID = 1;
|
||||
const PRINCIPAL = {
|
||||
origin: ORIGIN,
|
||||
appId: "123"
|
||||
appId: APP_ID
|
||||
};
|
||||
const PHONE_NUMBER = "+34666555444";
|
||||
const ANOTHER_PHONE_NUMBER = "+44123123123";
|
||||
@ -45,25 +46,25 @@ const CERTIFICATE = "eyJhbGciOiJEUzI1NiJ9.eyJsYXN0QXV0aEF0IjoxNDA0NDY5NzkyODc3LC
|
||||
|
||||
// === Helpers ===
|
||||
|
||||
function addPermission(aOrigin, aAction) {
|
||||
function addPermission(aAction) {
|
||||
let uri = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService)
|
||||
.newURI(aOrigin, null, null);
|
||||
.newURI(ORIGIN, null, null);
|
||||
let _principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getNoAppCodebasePrincipal(uri);
|
||||
.getAppCodebasePrincipal(uri, APP_ID, false);
|
||||
let pm = Cc["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Ci.nsIPermissionManager);
|
||||
pm.addFromPrincipal(_principal, MOBILEID_PERM, aAction);
|
||||
}
|
||||
|
||||
function removePermission(aOrigin) {
|
||||
function removePermission() {
|
||||
let uri = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService)
|
||||
.newURI(aOrigin, null, null);
|
||||
.newURI(ORIGIN, null, null);
|
||||
let _principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Ci.nsIScriptSecurityManager)
|
||||
.getNoAppCodebasePrincipal(uri);
|
||||
.getAppCodebasePrincipal(uri, APP_ID, false);
|
||||
let pm = Cc["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Ci.nsIPermissionManager);
|
||||
pm.removeFromPrincipal(_principal, MOBILEID_PERM);
|
||||
@ -194,8 +195,16 @@ MockCredStore.prototype = {
|
||||
|
||||
getByOrigin: function() {
|
||||
this._spy("getByOrigin", arguments);
|
||||
return Promise.resolve(this._options.getByOriginResult ||
|
||||
this._getByOriginResult);
|
||||
let result = this._getByOriginResult;
|
||||
if (this._options.getByOriginResult) {
|
||||
if (Array.isArray(this._options.getByOriginResult)) {
|
||||
result = this._options.getByOriginResult.length ?
|
||||
this._options.getByOriginResult.shift() : null;
|
||||
} else {
|
||||
result = this._options.getByOriginResult;
|
||||
}
|
||||
}
|
||||
return Promise.resolve(result);
|
||||
},
|
||||
|
||||
getByMsisdn: function() {
|
||||
@ -223,6 +232,11 @@ MockCredStore.prototype = {
|
||||
removeOrigin: function() {
|
||||
this._spy("removeOrigin", arguments);
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
delete: function() {
|
||||
this._spy("delete", arguments);
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
@ -239,15 +253,11 @@ MockClient.prototype = {
|
||||
__proto__: Mock.prototype,
|
||||
|
||||
_discoverResult: {
|
||||
verificationMethods: ["sms/momt", "sms/mt"],
|
||||
verificationMethods: ["sms/mt"],
|
||||
verificationDetails: {
|
||||
"sms/mt": {
|
||||
mtSender: "123",
|
||||
url: "https://msisdn.accounts.firefox.com/v1/msisdn/sms/mt/verify"
|
||||
},
|
||||
"sms/momt": {
|
||||
mtSender: "123",
|
||||
moVerifier: "234"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -298,6 +308,12 @@ MockClient.prototype = {
|
||||
|
||||
sign: function() {
|
||||
this._spy("sign", arguments);
|
||||
if (this._options.signError) {
|
||||
let error = Array.isArray(this._options.signError) ?
|
||||
this._options.signError.shift() :
|
||||
this._options.signError;
|
||||
return Promise.reject(error);
|
||||
}
|
||||
return Promise.resolve(this._options.signResult || this._signResult);
|
||||
}
|
||||
};
|
||||
@ -347,6 +363,7 @@ function cleanup() {
|
||||
MobileIdentityManager.client = kMobileIdentityClient;
|
||||
MobileIdentityManager.ui = null;
|
||||
MobileIdentityManager.iccInfo = null;
|
||||
removePermission(ORIGIN);
|
||||
}
|
||||
|
||||
// Unregister mocks and restore original code.
|
||||
@ -374,17 +391,7 @@ add_test(function() {
|
||||
MobileIdentityManager.ui = ui;
|
||||
let credStore = new MockCredStore();
|
||||
MobileIdentityManager.credStore = credStore;
|
||||
let client = new MockClient({
|
||||
discoverResult: {
|
||||
verificationMethods: ["sms/mt"],
|
||||
verificationDetails: {
|
||||
"sms/mt": {
|
||||
mtSender: "123",
|
||||
url: "https://msisdn.accounts.firefox.com/v1/msisdn/sms/mt/verify"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
let client = new MockClient();
|
||||
MobileIdentityManager.client = client;
|
||||
|
||||
let promiseId = Date.now();
|
||||
@ -442,6 +449,8 @@ add_test(function() {
|
||||
}
|
||||
};
|
||||
|
||||
addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
MobileIdentityManager.receiveMessage({
|
||||
name: GET_ASSERTION_IPC_MSG,
|
||||
principal: PRINCIPAL,
|
||||
@ -615,15 +624,6 @@ add_test(function() {
|
||||
let credStore = new MockCredStore();
|
||||
MobileIdentityManager.credStore = credStore;
|
||||
let client = new MockClient({
|
||||
discoverResult: {
|
||||
verificationMethods: ["sms/mt"],
|
||||
verificationDetails: {
|
||||
"sms/mt": {
|
||||
mtSender: "123",
|
||||
url: "https://msisdn.accounts.firefox.com/v1/msisdn/sms/mt/verify"
|
||||
}
|
||||
}
|
||||
},
|
||||
signResult: {
|
||||
cert: "aInvalidCert"
|
||||
},
|
||||
@ -739,7 +739,7 @@ add_test(function() {
|
||||
}
|
||||
};
|
||||
|
||||
addPermission(ORIGIN, Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
MobileIdentityManager.receiveMessage({
|
||||
name: GET_ASSERTION_IPC_MSG,
|
||||
@ -799,7 +799,7 @@ add_test(function() {
|
||||
}
|
||||
};
|
||||
|
||||
addPermission(ORIGIN, Ci.nsIPermissionManager.PROMPT_ACTION);
|
||||
addPermission(Ci.nsIPermissionManager.PROMPT_ACTION);
|
||||
|
||||
MobileIdentityManager.receiveMessage({
|
||||
name: GET_ASSERTION_IPC_MSG,
|
||||
@ -813,7 +813,7 @@ add_test(function() {
|
||||
});
|
||||
|
||||
add_test(function() {
|
||||
do_print("= Existing credentials - No Icc - Permission denied - OK result =");
|
||||
do_print("= Existing credentials - No Icc - Permission denied - KO result =");
|
||||
|
||||
do_register_cleanup(cleanup);
|
||||
|
||||
@ -847,13 +847,11 @@ add_test(function() {
|
||||
// Check spied calls.
|
||||
|
||||
// MockCredStore.
|
||||
credStore._("getByOrigin").callsLength(1);
|
||||
credStore._("getByOrigin").call(1).arg(1, ORIGIN);
|
||||
credStore._("getByOrigin").callsLength(0);
|
||||
|
||||
// MockUI.
|
||||
ui._("startFlow").callsLength(0);
|
||||
ui._("error").callsLength(1);
|
||||
ui._("error").call(1).arg(1, ERROR_PERMISSION_DENIED);
|
||||
ui._("error").callsLength(0);
|
||||
|
||||
do_test_finished();
|
||||
run_next_test();
|
||||
@ -937,6 +935,8 @@ add_test(function() {
|
||||
}
|
||||
};
|
||||
|
||||
addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
MobileIdentityManager.receiveMessage({
|
||||
name: GET_ASSERTION_IPC_MSG,
|
||||
principal: PRINCIPAL,
|
||||
@ -977,15 +977,6 @@ add_test(function() {
|
||||
MobileIdentityManager.credStore = credStore;
|
||||
let client = new MockClient({
|
||||
verifyCodeResult: ANOTHER_PHONE_NUMBER,
|
||||
discoverResult: {
|
||||
verificationMethods: ["sms/mt"],
|
||||
verificationDetails: {
|
||||
"sms/mt": {
|
||||
mtSender: "123",
|
||||
url: "https://msisdn.accounts.firefox.com/v1/msisdn/sms/mt/verify"
|
||||
}
|
||||
}
|
||||
},
|
||||
registerResult: {
|
||||
msisdnSessionToken: _sessionToken
|
||||
}
|
||||
@ -1161,15 +1152,6 @@ add_test(function() {
|
||||
MobileIdentityManager.credStore = credStore;
|
||||
let client = new MockClient({
|
||||
verifyCodeResult: ANOTHER_PHONE_NUMBER,
|
||||
discoverResult: {
|
||||
verificationMethods: ["sms/mt"],
|
||||
verificationDetails: {
|
||||
"sms/mt": {
|
||||
mtSender: "123",
|
||||
url: "https://msisdn.accounts.firefox.com/v1/msisdn/sms/mt/verify"
|
||||
}
|
||||
}
|
||||
},
|
||||
registerResult: {
|
||||
msisdnSessionToken: _sessionToken
|
||||
}
|
||||
@ -1233,3 +1215,96 @@ add_test(function() {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function() {
|
||||
do_print("= Existing credentials - No Icc - INVALID_AUTH_TOKEN - OK =");
|
||||
|
||||
do_register_cleanup(cleanup);
|
||||
|
||||
do_test_pending();
|
||||
|
||||
let _sessionToken = Date.now();
|
||||
|
||||
let existingCredentials = {
|
||||
sessionToken: _sessionToken,
|
||||
msisdn: PHONE_NUMBER,
|
||||
origin: ORIGIN,
|
||||
deviceIccIds: null
|
||||
};
|
||||
|
||||
let ui = new MockUi({
|
||||
startFlowResult: {
|
||||
phoneNumber: PHONE_NUMBER
|
||||
}
|
||||
});
|
||||
MobileIdentityManager.ui = ui;
|
||||
let credStore = new MockCredStore({
|
||||
getByOriginResult: [existingCredentials, null]
|
||||
});
|
||||
MobileIdentityManager.credStore = credStore;
|
||||
let client = new MockClient({
|
||||
signError: [ERROR_INVALID_AUTH_TOKEN],
|
||||
verifyCodeResult: PHONE_NUMBER,
|
||||
registerResult: {
|
||||
msisdnSessionToken: SESSION_TOKEN
|
||||
}
|
||||
});
|
||||
MobileIdentityManager.client = client;
|
||||
|
||||
let promiseId = Date.now();
|
||||
let mm = {
|
||||
sendAsyncMessage: function(aMsg, aData) {
|
||||
do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
|
||||
|
||||
// Check result.
|
||||
do_check_eq(aMsg, GET_ASSERTION_RETURN_OK);
|
||||
do_check_eq(typeof aData, "object");
|
||||
do_check_eq(aData.promiseId, promiseId);
|
||||
|
||||
// Check spied calls.
|
||||
|
||||
// MockCredStore.
|
||||
credStore._("getByOrigin").callsLength(2);
|
||||
credStore._("getByOrigin").call(1).arg(1, ORIGIN);
|
||||
credStore._("getByOrigin").call(2).arg(1, ORIGIN);
|
||||
credStore._("getByMsisdn").callsLength(1);
|
||||
credStore._("getByMsisdn").call(1).arg(1, PHONE_NUMBER);
|
||||
credStore._("add").callsLength(1);
|
||||
credStore._("add").call(1).arg(1, undefined);
|
||||
credStore._("add").call(1).arg(2, PHONE_NUMBER);
|
||||
credStore._("add").call(1).arg(3, ORIGIN);
|
||||
credStore._("add").call(1).arg(4, SESSION_TOKEN);
|
||||
credStore._("add").call(1).arg(5, null);
|
||||
credStore._("setDeviceIccIds").callsLength(0);
|
||||
credStore._("delete").callsLength(1);
|
||||
credStore._("delete").call(1).arg(1, PHONE_NUMBER);
|
||||
|
||||
// MockUI.
|
||||
ui._("startFlow").callsLength(1);
|
||||
ui._("verifyCodePrompt").callsLength(1);
|
||||
ui._("verify").callsLength(1);
|
||||
|
||||
// MockClient.
|
||||
client._("discover").callsLength(1);
|
||||
client._("register").callsLength(1);
|
||||
client._("smsMtVerify").callsLength(1);
|
||||
client._("verifyCode").callsLength(1);
|
||||
client._("sign").callsLength(1);
|
||||
|
||||
do_test_finished();
|
||||
run_next_test();
|
||||
}
|
||||
};
|
||||
|
||||
addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
MobileIdentityManager.receiveMessage({
|
||||
name: GET_ASSERTION_IPC_MSG,
|
||||
principal: PRINCIPAL,
|
||||
target: mm,
|
||||
json: {
|
||||
promiseId: promiseId,
|
||||
options: {}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -102,11 +102,16 @@ FxAccountsService.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
cleanupRPRequest: function(aRp) {
|
||||
aRp.pendingRequest = false;
|
||||
this._rpFlows.set(aRp.id, aRp);
|
||||
},
|
||||
|
||||
/**
|
||||
* Register a listener for a given windowID as a result of a call to
|
||||
* navigator.id.watch().
|
||||
*
|
||||
* @param aCaller
|
||||
* @param aRPCaller
|
||||
* (Object) an object that represents the caller document, and
|
||||
* is expected to have properties:
|
||||
* - id (unique, e.g. uuid)
|
||||
@ -128,7 +133,9 @@ FxAccountsService.prototype = {
|
||||
// Log the user in, if possible, and then call ready().
|
||||
let runnable = {
|
||||
run: () => {
|
||||
this.fxAccountsManager.getAssertion(aRpCaller.audience, {silent:true}).then(
|
||||
this.fxAccountsManager.getAssertion(aRpCaller.audience,
|
||||
aRpCaller.principal,
|
||||
{ silent:true }).then(
|
||||
data => {
|
||||
if (data) {
|
||||
this.doLogin(aRpCaller.id, data);
|
||||
@ -161,10 +168,10 @@ FxAccountsService.prototype = {
|
||||
* navigator.id.request().
|
||||
*
|
||||
* @param aRPId
|
||||
* (integer) the id of the doc object obtained in .watch()
|
||||
* (integer) the id of the doc object obtained in .watch()
|
||||
*
|
||||
* @param aOptions
|
||||
* (Object) options including privacyPolicy, termsOfService
|
||||
* (Object) options including privacyPolicy, termsOfService
|
||||
*/
|
||||
request: function request(aRPId, aOptions) {
|
||||
aOptions = aOptions || {};
|
||||
@ -174,24 +181,48 @@ FxAccountsService.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
// We check if we already have a pending request for this RP and in that
|
||||
// case we just bail out. We don't want duplicated onlogin or oncancel
|
||||
// events.
|
||||
if (rp.pendingRequest) {
|
||||
log.debug("request() already called");
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, we set the RP flow with the pending request flag.
|
||||
rp.pendingRequest = true;
|
||||
this._rpFlows.set(rp.id, rp);
|
||||
|
||||
let options = makeMessageObject(rp);
|
||||
objectCopy(aOptions, options);
|
||||
|
||||
log.debug("get assertion for " + rp.audience);
|
||||
|
||||
this.fxAccountsManager.getAssertion(rp.audience, options).then(
|
||||
this.fxAccountsManager.getAssertion(rp.audience, rp.principal, options)
|
||||
.then(
|
||||
data => {
|
||||
log.debug("got assertion for " + rp.audience + ": " + data);
|
||||
this.doLogin(aRPId, data);
|
||||
},
|
||||
error => {
|
||||
log.error("get assertion failed: " + JSON.stringify(error));
|
||||
log.debug("get assertion failed: " + JSON.stringify(error));
|
||||
// Cancellation is passed through an error channel; here we reroute.
|
||||
if (error.error && (error.error.details == "DIALOG_CLOSED_BY_USER")) {
|
||||
if ((error.error && (error.error.details == "DIALOG_CLOSED_BY_USER")) ||
|
||||
(error.details == "DIALOG_CLOSED_BY_USER")) {
|
||||
return this.doCancel(aRPId);
|
||||
}
|
||||
this.doError(aRPId, error);
|
||||
}
|
||||
)
|
||||
.then(
|
||||
() => {
|
||||
this.cleanupRPRequest(rp);
|
||||
}
|
||||
)
|
||||
.catch(
|
||||
() => {
|
||||
this.cleanupRPRequest(rp);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -982,6 +982,11 @@ nsAppShell::Init()
|
||||
InitGonkMemoryPressureMonitoring();
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
printf("*****************************************************************\n");
|
||||
printf("***\n");
|
||||
printf("*** This is stdout. Most of the useful output will be in logcat.\n");
|
||||
printf("***\n");
|
||||
printf("*****************************************************************\n");
|
||||
#ifdef MOZ_OMX_DECODER
|
||||
android::MediaResourceManagerService::instantiate();
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user