Bug 1399070 move launchWebAuthFlow to parent to fix opening auth window when remote, r=zombie
MozReview-Commit-ID: GAdlxYUM6rr
--- a/browser/components/extensions/ext-browser.json
+++ b/browser/components/extensions/ext-browser.json
@@ -84,18 +84,22 @@
"url": "chrome://browser/content/ext-history.js",
"schema": "chrome://browser/content/schemas/history.json",
"scopes": ["addon_parent"],
"paths": [
["history"]
]
},
"identity": {
+ "url": "chrome://extensions/content/ext-identity.js",
"schema": "chrome://extensions/content/schemas/identity.json",
- "scopes": ["addon_parent"]
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["identity"]
+ ]
},
"menusInternal": {
"url": "chrome://browser/content/ext-menus.js",
"schema": "chrome://browser/content/schemas/menus.json",
"scopes": ["addon_parent"],
"paths": [
["menusInternal"]
]
--- a/toolkit/components/extensions/ext-c-identity.js
+++ b/toolkit/components/extensions/ext-c-identity.js
@@ -1,155 +1,35 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
var {Constructor: CC} = Components;
-XPCOMUtils.defineLazyModuleGetter(this, "Services",
- "resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils",
"resource://services-common/utils.js");
XPCOMUtils.defineLazyPreferenceGetter(this, "redirectDomain",
"extensions.webextensions.identity.redirectDomain");
let CryptoHash = CC("@mozilla.org/security/hash;1", "nsICryptoHash", "initWithString");
-Cu.importGlobalProperties(["URL", "XMLHttpRequest", "TextEncoder"]);
-
-var {
- promiseDocumentLoaded,
-} = ExtensionUtils;
+Cu.importGlobalProperties(["URL", "TextEncoder"]);
const computeHash = str => {
let byteArr = new TextEncoder().encode(str);
let hash = new CryptoHash("sha1");
hash.update(byteArr, byteArr.length);
return CommonUtils.bytesAsHex(hash.finish(false));
};
-const checkRedirected = (url, redirectURI) => {
- return new Promise((resolve, reject) => {
- let xhr = new XMLHttpRequest();
- xhr.open("HEAD", url);
- // We expect this if the user has not authenticated.
- xhr.onload = () => {
- reject(0);
- };
- // An unexpected error happened, log for extension authors.
- xhr.onerror = () => {
- reject(xhr.status);
- };
- // Catch redirect to our redirect_uri before a new request is made.
- xhr.channel.notificationCallbacks = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterfaceRequestor, Ci.nsIChannelEventSync]),
-
- getInterface: XPCOMUtils.generateQI([Ci.nsIChannelEventSink]),
-
- asyncOnChannelRedirect(oldChannel, newChannel, flags, callback) {
- let responseURL = newChannel.URI.spec;
- if (responseURL.startsWith(redirectURI)) {
- resolve(responseURL);
- // Cancel the redirect.
- callback.onRedirectVerifyCallback(Components.results.NS_BINDING_ABORTED);
- return;
- }
- callback.onRedirectVerifyCallback(Components.results.NS_OK);
- },
- };
- xhr.send();
- });
-};
-
-const openOAuthWindow = (details, redirectURI) => {
- let args = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
- let supportsStringPrefURL = Cc["@mozilla.org/supports-string;1"]
- .createInstance(Ci.nsISupportsString);
- supportsStringPrefURL.data = details.url;
- args.appendElement(supportsStringPrefURL);
-
- let window = Services.ww.openWindow(null,
- Services.prefs.getCharPref("browser.chromeURL"),
- "launchWebAuthFlow_dialog",
- "chrome,location=yes,centerscreen,dialog=no,resizable=yes",
- args);
-
- return new Promise((resolve, reject) => {
- let wpl;
-
- // If the user just closes the window we need to reject
- function unloadlistener() {
- window.removeEventListener("unload", unloadlistener);
- window.gBrowser.removeTabsProgressListener(wpl);
- reject({message: "User cancelled or denied access."});
- }
-
- wpl = {
- onLocationChange(browser, webProgress, request, locationURI) {
- if (locationURI.spec.startsWith(redirectURI)) {
- resolve(locationURI.spec);
- window.removeEventListener("unload", unloadlistener);
- window.gBrowser.removeTabsProgressListener(wpl);
- window.close();
- }
- },
- onProgressChange() {},
- onStatusChange() {},
- onSecurityChange() {},
- };
-
- promiseDocumentLoaded(window.document).then(() => {
- window.gBrowser.addTabsProgressListener(wpl);
- window.addEventListener("unload", unloadlistener);
- });
- });
-};
-
this.identity = class extends ExtensionAPI {
getAPI(context) {
let {extension} = context;
return {
identity: {
- launchWebAuthFlow: function(details) {
- // In OAuth2 the url should have a redirect_uri param, parse the url and grab it
- let url, redirectURI;
- try {
- url = new URL(details.url);
- } catch (e) {
- return Promise.reject({message: "details.url is invalid"});
- }
- try {
- redirectURI = new URL(url.searchParams.get("redirect_uri"));
- if (!redirectURI) {
- return Promise.reject({message: "redirect_uri is missing"});
- }
- } catch (e) {
- return Promise.reject({message: "redirect_uri is invalid"});
- }
- if (!redirectURI.href.startsWith(this.getRedirectURL())) {
- // Any url will work, but we suggest addons use getRedirectURL.
- Services.console.logStringMessage("WebExtensions: redirect_uri should use browser.identity.getRedirectURL");
- }
-
- // If the request is automatically redirected the user has already
- // authorized and we do not want to show the window.
- return checkRedirected(details.url, redirectURI).catch((requestError) => {
- // requestError is zero or xhr.status
- if (requestError !== 0) {
- Cu.reportError(`browser.identity auth check failed with ${requestError}`);
- return Promise.reject({message: "Invalid request"});
- }
- if (!details.interactive) {
- return Promise.reject({message: `Requires user interaction`});
- }
-
- return openOAuthWindow(details, redirectURI);
- });
- },
-
getRedirectURL: function(path = "") {
let hash = computeHash(extension.id);
let url = new URL(`https://${hash}.${redirectDomain}/`);
url.pathname = path;
return url.href;
},
},
};
copy from toolkit/components/extensions/ext-c-identity.js
copy to toolkit/components/extensions/ext-identity.js
--- a/toolkit/components/extensions/ext-c-identity.js
+++ b/toolkit/components/extensions/ext-identity.js
@@ -1,36 +1,21 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
-var {Constructor: CC} = Components;
-
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils",
- "resource://services-common/utils.js");
-XPCOMUtils.defineLazyPreferenceGetter(this, "redirectDomain",
- "extensions.webextensions.identity.redirectDomain");
-let CryptoHash = CC("@mozilla.org/security/hash;1", "nsICryptoHash", "initWithString");
-
-Cu.importGlobalProperties(["URL", "XMLHttpRequest", "TextEncoder"]);
+Cu.importGlobalProperties(["URL", "XMLHttpRequest"]);
var {
promiseDocumentLoaded,
} = ExtensionUtils;
-const computeHash = str => {
- let byteArr = new TextEncoder().encode(str);
- let hash = new CryptoHash("sha1");
- hash.update(byteArr, byteArr.length);
- return CommonUtils.bytesAsHex(hash.finish(false));
-};
-
const checkRedirected = (url, redirectURI) => {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open("HEAD", url);
// We expect this if the user has not authenticated.
xhr.onload = () => {
reject(0);
};
@@ -100,17 +85,16 @@ const openOAuthWindow = (details, redire
window.gBrowser.addTabsProgressListener(wpl);
window.addEventListener("unload", unloadlistener);
});
});
};
this.identity = class extends ExtensionAPI {
getAPI(context) {
- let {extension} = context;
return {
identity: {
launchWebAuthFlow: function(details) {
// In OAuth2 the url should have a redirect_uri param, parse the url and grab it
let url, redirectURI;
try {
url = new URL(details.url);
} catch (e) {
@@ -119,39 +103,28 @@ this.identity = class extends ExtensionA
try {
redirectURI = new URL(url.searchParams.get("redirect_uri"));
if (!redirectURI) {
return Promise.reject({message: "redirect_uri is missing"});
}
} catch (e) {
return Promise.reject({message: "redirect_uri is invalid"});
}
- if (!redirectURI.href.startsWith(this.getRedirectURL())) {
- // Any url will work, but we suggest addons use getRedirectURL.
- Services.console.logStringMessage("WebExtensions: redirect_uri should use browser.identity.getRedirectURL");
- }
// If the request is automatically redirected the user has already
// authorized and we do not want to show the window.
return checkRedirected(details.url, redirectURI).catch((requestError) => {
// requestError is zero or xhr.status
if (requestError !== 0) {
Cu.reportError(`browser.identity auth check failed with ${requestError}`);
return Promise.reject({message: "Invalid request"});
}
if (!details.interactive) {
return Promise.reject({message: `Requires user interaction`});
}
return openOAuthWindow(details, redirectURI);
});
},
-
- getRedirectURL: function(path = "") {
- let hash = computeHash(extension.id);
- let url = new URL(`https://${hash}.${redirectDomain}/`);
- url.pathname = path;
- return url.href;
- },
},
};
}
};
--- a/toolkit/components/extensions/jar.mn
+++ b/toolkit/components/extensions/jar.mn
@@ -10,16 +10,19 @@ toolkit.jar:
content/extensions/ext-browser-content.js
content/extensions/ext-browserSettings.js
content/extensions/ext-contextualIdentities.js
content/extensions/ext-clipboard.js
content/extensions/ext-cookies.js
content/extensions/ext-downloads.js
content/extensions/ext-extension.js
content/extensions/ext-i18n.js
+#ifndef ANDROID
+ content/extensions/ext-identity.js
+#endif
content/extensions/ext-idle.js
content/extensions/ext-management.js
content/extensions/ext-notifications.js
content/extensions/ext-permissions.js
content/extensions/ext-privacy.js
content/extensions/ext-protocolHandlers.js
content/extensions/ext-proxy.js
content/extensions/ext-runtime.js