@metamask/snaps-utils
Advanced tools
Comparing version 4.0.0 to 4.0.1
@@ -9,2 +9,6 @@ # Changelog | ||
## [4.0.1] | ||
### Fixed | ||
- Change `validateTextLinks` to only get URL in markdown links ([#1914](https://github.com/MetaMask/snaps/pull/1914)) | ||
## [4.0.0] | ||
@@ -107,3 +111,4 @@ ### Changed | ||
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@4.0.0...HEAD | ||
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@4.0.1...HEAD | ||
[4.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@4.0.0...@metamask/snaps-utils@4.0.1 | ||
[4.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@3.3.0...@metamask/snaps-utils@4.0.0 | ||
@@ -110,0 +115,0 @@ [3.3.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@3.2.0...@metamask/snaps-utils@3.3.0 |
@@ -21,3 +21,3 @@ "use strict"; | ||
const _utils = require("@metamask/utils"); | ||
const LINK_REGEX = RegExp("(?<protocol>[a-z]+:\\/?\\/?)(?<host>\\S+?(?:\\.[a-z]+)+)", "giu"); | ||
const MARKDOWN_LINK_REGEX = RegExp("\\[(?<name>[^\\]]*)\\]\\((?<url>[^)]+)\\)", "giu"); | ||
const ALLOWED_PROTOCOLS = [ | ||
@@ -28,14 +28,16 @@ 'https:', | ||
function validateTextLinks(text, isOnPhishingList) { | ||
const links = text.match(LINK_REGEX); | ||
if (links) { | ||
links.forEach((link)=>{ | ||
try { | ||
const url = new URL(link); | ||
(0, _utils.assert)(ALLOWED_PROTOCOLS.includes(url.protocol), `Protocol must be one of: ${ALLOWED_PROTOCOLS.join(', ')}.`); | ||
const hostname = url.protocol === 'mailto:' ? url.pathname.split('@')[1] : url.hostname; | ||
(0, _utils.assert)(!isOnPhishingList(hostname), 'The specified URL is not allowed.'); | ||
} catch (error) { | ||
throw new Error(`Invalid URL: ${error instanceof _utils.AssertionError ? error.message : 'Unable to parse URL.'}`); | ||
} | ||
}); | ||
const matches = String.prototype.matchAll.call(text, MARKDOWN_LINK_REGEX); | ||
for (const { groups } of matches){ | ||
const link = groups?.url; | ||
/* This case should never happen with the regex but the TS type allows for undefined */ /* istanbul ignore next */ if (!link) { | ||
continue; | ||
} | ||
try { | ||
const url = new URL(link); | ||
(0, _utils.assert)(ALLOWED_PROTOCOLS.includes(url.protocol), `Protocol must be one of: ${ALLOWED_PROTOCOLS.join(', ')}.`); | ||
const hostname = url.protocol === 'mailto:' ? url.pathname.split('@')[1] : url.hostname; | ||
(0, _utils.assert)(!isOnPhishingList(hostname), 'The specified URL is not allowed.'); | ||
} catch (error) { | ||
throw new Error(`Invalid URL: ${error instanceof _utils.AssertionError ? error.message : 'Unable to parse URL.'}`); | ||
} | ||
} | ||
@@ -48,3 +50,3 @@ } | ||
} | ||
if ((0, _utils.hasProperty)(component, 'value') && typeof component.value === 'string') { | ||
if (type === _snapssdk.NodeType.Text) { | ||
validateTextLinks(component.value, isOnPhishingList); | ||
@@ -51,0 +53,0 @@ } |
import { NodeType } from '@metamask/snaps-sdk'; | ||
import { assert, AssertionError, hasProperty } from '@metamask/utils'; | ||
const LINK_REGEX = RegExp("(?<protocol>[a-z]+:\\/?\\/?)(?<host>\\S+?(?:\\.[a-z]+)+)", "giu"); | ||
import { assert, AssertionError } from '@metamask/utils'; | ||
const MARKDOWN_LINK_REGEX = RegExp("\\[(?<name>[^\\]]*)\\]\\((?<url>[^)]+)\\)", "giu"); | ||
const ALLOWED_PROTOCOLS = [ | ||
@@ -9,3 +9,3 @@ 'https:', | ||
/** | ||
* Search for links in a sting and check them against the phishing list. | ||
* Searches for markdown links in a string and checks them against the phishing list. | ||
* | ||
@@ -17,14 +17,16 @@ * @param text - The text to verify. | ||
*/ export function validateTextLinks(text, isOnPhishingList) { | ||
const links = text.match(LINK_REGEX); | ||
if (links) { | ||
links.forEach((link)=>{ | ||
try { | ||
const url = new URL(link); | ||
assert(ALLOWED_PROTOCOLS.includes(url.protocol), `Protocol must be one of: ${ALLOWED_PROTOCOLS.join(', ')}.`); | ||
const hostname = url.protocol === 'mailto:' ? url.pathname.split('@')[1] : url.hostname; | ||
assert(!isOnPhishingList(hostname), 'The specified URL is not allowed.'); | ||
} catch (error) { | ||
throw new Error(`Invalid URL: ${error instanceof AssertionError ? error.message : 'Unable to parse URL.'}`); | ||
} | ||
}); | ||
const matches = String.prototype.matchAll.call(text, MARKDOWN_LINK_REGEX); | ||
for (const { groups } of matches){ | ||
const link = groups?.url; | ||
/* This case should never happen with the regex but the TS type allows for undefined */ /* istanbul ignore next */ if (!link) { | ||
continue; | ||
} | ||
try { | ||
const url = new URL(link); | ||
assert(ALLOWED_PROTOCOLS.includes(url.protocol), `Protocol must be one of: ${ALLOWED_PROTOCOLS.join(', ')}.`); | ||
const hostname = url.protocol === 'mailto:' ? url.pathname.split('@')[1] : url.hostname; | ||
assert(!isOnPhishingList(hostname), 'The specified URL is not allowed.'); | ||
} catch (error) { | ||
throw new Error(`Invalid URL: ${error instanceof AssertionError ? error.message : 'Unable to parse URL.'}`); | ||
} | ||
} | ||
@@ -45,3 +47,3 @@ } | ||
} | ||
if (hasProperty(component, 'value') && typeof component.value === 'string') { | ||
if (type === NodeType.Text) { | ||
validateTextLinks(component.value, isOnPhishingList); | ||
@@ -48,0 +50,0 @@ } |
import type { Component } from '@metamask/snaps-sdk'; | ||
/** | ||
* Search for links in a sting and check them against the phishing list. | ||
* Searches for markdown links in a string and checks them against the phishing list. | ||
* | ||
@@ -5,0 +5,0 @@ * @param text - The text to verify. |
{ | ||
"name": "@metamask/snaps-utils", | ||
"version": "4.0.0", | ||
"version": "4.0.1", | ||
"repository": { | ||
@@ -75,3 +75,3 @@ "type": "git", | ||
"@metamask/snaps-registry": "^2.1.0", | ||
"@metamask/snaps-sdk": "^1.0.0", | ||
"@metamask/snaps-sdk": "^1.1.0", | ||
"@metamask/utils": "^8.1.0", | ||
@@ -78,0 +78,0 @@ "@noble/hashes": "^1.3.1", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
760965
8640
Updated@metamask/snaps-sdk@^1.1.0