summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/ExtensionPermissions.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--toolkit/components/extensions/ExtensionPermissions.sys.mjs52
1 files changed, 50 insertions, 2 deletions
diff --git a/toolkit/components/extensions/ExtensionPermissions.sys.mjs b/toolkit/components/extensions/ExtensionPermissions.sys.mjs
index 1ee9afdc32..964503d8f6 100644
--- a/toolkit/components/extensions/ExtensionPermissions.sys.mjs
+++ b/toolkit/components/extensions/ExtensionPermissions.sys.mjs
@@ -8,11 +8,13 @@ import { computeSha1HashAsString } from "resource://gre/modules/addons/crypto-ut
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs";
+/** @type {Lazy} */
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
AddonManager: "resource://gre/modules/AddonManager.sys.mjs",
AddonManagerPrivate: "resource://gre/modules/AddonManager.sys.mjs",
+ Extension: "resource://gre/modules/Extension.sys.mjs",
ExtensionParent: "resource://gre/modules/ExtensionParent.sys.mjs",
FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
JSONFile: "resource://gre/modules/JSONFile.sys.mjs",
@@ -347,6 +349,50 @@ export var ExtensionPermissions = {
return this._getCached(extensionId);
},
+ /**
+ * Validate and normalize passed in `perms`, including a fixup to
+ * include all possible "all sites" permissions when appropriate.
+ *
+ * @throws if an origin or permission is not part of optional permissions.
+ *
+ * @typedef {object} Perms
+ * @property {string[]} origins
+ * @property {string[]} permissions
+ *
+ * @param {Perms} perms api permissions and origins to be added/removed.
+ * @param {Perms} optional permissions and origins from the manifest.
+ * @returns {Perms} normalized
+ */
+ normalizeOptional(perms, optional) {
+ let allSites = false;
+ let patterns = new MatchPatternSet(optional.origins, { ignorePath: true });
+ let normalized = Object.assign({}, perms);
+
+ for (let o of perms.origins) {
+ if (!patterns.subsumes(new MatchPattern(o))) {
+ throw new Error(`${o} was not declared in the manifest`);
+ }
+ // If this is one of the "all sites" permissions
+ allSites ||= lazy.Extension.isAllSitesPermission(o);
+ }
+
+ if (allSites) {
+ // Grant/revoke ALL "all sites" optional permissions from the manifest.
+ let origins = perms.origins.concat(
+ optional.origins.filter(o => lazy.Extension.isAllSitesPermission(o))
+ );
+ normalized.origins = Array.from(new Set(origins));
+ }
+
+ for (let p of perms.permissions) {
+ if (!optional.permissions.includes(p)) {
+ throw new Error(`${p} was not declared in optional_permissions`);
+ }
+ }
+
+ return normalized;
+ },
+
_fixupAllUrlsPerms(perms) {
// Unfortunately, we treat <all_urls> as an API permission as well.
// If it is added to either, ensure it is added to both.
@@ -361,8 +407,10 @@ export var ExtensionPermissions = {
* Add new permissions for the given extension. `permissions` is
* in the format that is passed to browser.permissions.request().
*
+ * @typedef {import("ExtensionCommon.sys.mjs").EventEmitter} EventEmitter
+ *
* @param {string} extensionId The extension id
- * @param {object} perms Object with permissions and origins array.
+ * @param {Perms} perms Object with permissions and origins array.
* @param {EventEmitter} [emitter] optional object implementing emitter interfaces
*/
async add(extensionId, perms, emitter) {
@@ -401,7 +449,7 @@ export var ExtensionPermissions = {
* in the format that is passed to browser.permissions.request().
*
* @param {string} extensionId The extension id
- * @param {object} perms Object with permissions and origins array.
+ * @param {Perms} perms Object with permissions and origins array.
* @param {EventEmitter} [emitter] optional object implementing emitter interfaces
*/
async remove(extensionId, perms, emitter) {