diff --git a/.gitignore b/.gitignore index 977cfa6..939ae6e 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,6 @@ typings/ # next.js build output .next dist + +# jetbrain IDE files +/.idea diff --git a/docs/configuration.md b/docs/configuration.md index 7c4b17a..2b673e3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -154,4 +154,10 @@ To configure domains, add a `` element + + + ``` diff --git a/src/api/js-api-util.js b/src/api/js-api-util.js new file mode 100644 index 0000000..60c27cd --- /dev/null +++ b/src/api/js-api-util.js @@ -0,0 +1,10 @@ +// from https://github.com/sindresorhus/escape-string-regexp +export const escapeStringRegexp = (string) => { + if (typeof string !== "string") { + throw new TypeError("Expected a string"); + } + + // Escape characters with special meaning either inside or outside character sets. + // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. + return string.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"); +}; diff --git a/src/api/js-api.js b/src/api/js-api.js index efd713c..7f175ed 100644 --- a/src/api/js-api.js +++ b/src/api/js-api.js @@ -1,3 +1,5 @@ +import { escapeStringRegexp } from "./js-api-util"; + const localStoragePrefix = "import-map-override:"; const disabledOverridesLocalStorageKey = "import-map-overrides-disabled"; const externalOverridesLocalStorageKey = "import-map-overrides-external-maps"; @@ -27,16 +29,16 @@ if (domainsElement) { if (!content) { console.warn(`Invalid ${domainsMeta} meta element - content required.`); } + + const matchHostname = (domain) => + new RegExp(escapeStringRegexp(domain).replace("*", ".+")).test(domain); + if (content.indexOf(allowListPrefix) === 0) { const allowedDomains = content.slice(allowListPrefix.length).split(","); - isDisabled = !allowedDomains.some( - (allowedDomain) => window.location.hostname === allowedDomain - ); + isDisabled = !allowedDomains.some(matchHostname); } else if (content.indexOf(denyListPrefix) === 0) { const deniedDomains = content.slice(denyListPrefix.length).split(","); - isDisabled = deniedDomains.some( - (deniedDomain) => deniedDomain === window.location.hostname - ); + isDisabled = deniedDomains.some(matchHostname); } else { console.log( `Invalid ${domainsMeta} meta content attribute - must start with ${allowListPrefix} or ${denyListPrefix}` diff --git a/test/deny-list.html b/test/deny-list.html new file mode 100644 index 0000000..49c537e --- /dev/null +++ b/test/deny-list.html @@ -0,0 +1,22 @@ + + + + + + Import Map Overrides test + + + + + + + + + + + diff --git a/test/index.html b/test/index.html index da9b723..49aa4da 100644 --- a/test/index.html +++ b/test/index.html @@ -29,6 +29,7 @@
  • With embedded map (current)
  • Without embedded map
  • Server map
  • +
  • With deny list
  • diff --git a/test/no-map.html b/test/no-map.html index 9f09429..0e153ab 100644 --- a/test/no-map.html +++ b/test/no-map.html @@ -14,6 +14,8 @@ diff --git a/test/server-map.html b/test/server-map.html index dfe8d2a..2a92cb0 100644 --- a/test/server-map.html +++ b/test/server-map.html @@ -27,6 +27,7 @@
  • With embedded map
  • Without embedded map
  • Server map (current)
  • +
  • With deny list