Socket
Socket
Sign inDemoInstall

is-ipfs

Package Overview
Dependencies
7
Maintainers
2
Versions
35
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.6.3 to 1.0.0

dist/index.min.js.LICENSE.txt

55

CHANGELOG.md

@@ -0,1 +1,56 @@

<a name="1.0.0"></a>
# [1.0.0](https://github.com/ipfs/is-ipfs/compare/v0.6.3...v1.0.0) (2020-04-05)
### Features
* support subdomains in isIPFS.url(url) ([#32](https://github.com/ipfs/is-ipfs/issues/32)) ([22d001d](https://github.com/ipfs/is-ipfs/commit/22d001d)), closes [/github.com/ipfs/is-ipfs/pull/32#discussion_r396161665](https://github.com//github.com/ipfs/is-ipfs/pull/32/issues/discussion_r396161665)
### BREAKING CHANGES
* `isIPFS.subdomain` now returns true for <domain.tld>.ipns.localhost
* `isIPFS.subdomainPattern` changed
* test: support peer multiaddr with /p2p/
Context: https://github.com/libp2p/libp2p/issues/79
* fix: explicitly ignore URL param and hash
.url and .path now return true when validating:
https://ipfs.io/ipfs/<CID>?filename=name.png#foo
* refactor: simplify dnslinkSubdomain
License: MIT
Signed-off-by: Marcin Rataj <lidel@lidel.org>
* fix: url() check should include subdomain()
When .url was created we only had path gateways. When .subdomain was
added, we did not update .url to test for subdomain gateways, which in
the long run will confuse people and feels like a bug.
Let's fix this: .url() will now check for both subdomain and path gateways
* .url(url) now returns true if .subdomain(url) is true
* refactor: merge DNSLink check into ipnsSubdomain()
This makes subdomain checks follow what path gateway checks do, removing
confusion.
In both cases (IPNS and DNSLink) user needs to perform online record
check, so this is just a handy way of detecting potential matches.
* docs: update examples
* refactor: switch to iso-url
* refactor: lint-package-json
* chore: update deps
License: MIT
Signed-off-by: Marcin Rataj <lidel@lidel.org>
<a name="0.6.3"></a>

@@ -2,0 +57,0 @@ ## [0.6.3](https://github.com/ipfs/is-ipfs/compare/v0.6.1...v0.6.3) (2020-01-07)

74

package.json
{
"name": "is-ipfs",
"version": "0.6.3",
"description": "A set of utilities to help identify IPFS resources",
"version": "1.0.0",
"description": "A set of utilities to help identify IPFS resources on the web",
"keywords": [
"js-ipfs",
"ipns",
"gateway",
"dnslink",
"ipfs"
],
"homepage": "https://github.com/ipfs/is-ipfs",
"bugs": {
"url": "https://github.com/ipfs/is-ipfs/issues"
},
"license": "MIT",
"author": "Francisco Dias <francisco@baiodias.com> (http://franciscodias.net/)",
"leadMaintainer": "Marcin Rataj <lidel@lidel.org>",
"files": [
"src",
"dist"
],
"main": "src/index.js",

@@ -10,2 +27,6 @@ "browser": {

},
"repository": {
"type": "git",
"url": "https://github.com/ipfs/is-ipfs.git"
},
"scripts": {

@@ -15,3 +36,3 @@ "test:node": "aegir test --target node",

"test": "aegir test",
"lint": "aegir lint",
"lint": "aegir lint && aegir lint-package-json",
"release": "aegir release",

@@ -24,41 +45,32 @@ "release-minor": "aegir release --type minor",

},
"pre-commit": [
"test",
"lint"
],
"keywords": [
"js-ipfs",
"ipfs"
],
"author": "Francisco Dias <francisco@baiodias.com> (http://franciscodias.net/)",
"license": "MIT",
"dependencies": {
"bs58": "^4.0.1",
"cids": "~0.7.0",
"mafmt": "^7.0.0",
"multiaddr": "^7.2.1",
"multibase": "~0.6.0",
"multihashes": "~0.4.13"
"cids": "~0.8.0",
"iso-url": "~0.4.7",
"mafmt": "^7.1.0",
"multiaddr": "^7.4.3",
"multibase": "~0.7.0",
"multihashes": "~0.4.19"
},
"devDependencies": {
"aegir": "^20.5.0",
"aegir": "^21.4.5",
"chai": "^4.2.0",
"pre-commit": "^1.2.2"
},
"repository": {
"type": "git",
"url": "https://github.com/ipfs/is-ipfs.git"
"engines": {
"node": ">=10.0.0",
"npm": ">=6.0.0"
},
"bugs": {
"url": "https://github.com/ipfs/is-ipfs/issues"
},
"homepage": "https://github.com/ipfs/is-ipfs",
"pre-commit": [
"test",
"lint"
],
"contributors": [
"Marcin Rataj <lidel@lidel.org>",
"Francisco Baio Dias <xicombd@gmail.com>",
"David Dias <daviddias.p@gmail.com>",
"Alan Shaw <alan.shaw@protocol.ai>",
"David Dias <daviddias.p@gmail.com>",
"Francisco Baio Dias <xicombd@gmail.com>",
"Henrique Dias <hacdias@gmail.com>",
"Marcin Rataj <lidel@lidel.org>",
"nginnever <ginneversource@gmail.com>"
"nginnever <ginneversource@gmail.com>",
"Henrique Dias <hacdias@gmail.com>"
]
}

@@ -26,3 +26,3 @@ is-ipfs 🕵️

```js
var isIPFS = require('is-ipfs')
const isIPFS = require('is-ipfs')
```

@@ -57,3 +57,6 @@

isIPFS.url('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true
isIPFS.url('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?filename=guardian.jpg') // true
isIPFS.url('https://ipfs.io/ipns/github.com') // true
isIPFS.url('https://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true
isIPFS.url('http://en.wikipedia-on-ipfs.org.ipfs.localhost:8080') // true
isIPFS.url('https://github.com/ipfs/js-ipfs/blob/master/README.md') // false

@@ -63,2 +66,3 @@ isIPFS.url('https://google.com') // false

isIPFS.path('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true
isIPFS.path('/ipfs/QmbcBPAwCDxRMB1Qe7CRQmxdrTSkxKwM9y6rZw2FjGtbsb/?weird-filename=test.jpg') // true
isIPFS.path('/ipns/github.com') // true

@@ -71,2 +75,3 @@ isIPFS.path('/ipfs/js-ipfs/blob/master/README.md') // false

isIPFS.urlOrPath('/ipns/github.com') // true
isIPFS.urlOrPath('https://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true
isIPFS.urlOrPath('https://google.com') // false

@@ -103,3 +108,4 @@

isIPFS.ipnsSubdomain('http://QmcNioXSC1bfJj1dcFErhUfyjFzoX2HodkRccsFFVJJvg8.ipns.dweb.link') // false
isIPFS.ipnsSubdomain('http://foo-bar.ipns.dweb.link') // false (not a PeerID)
isIPFS.ipnsSubdomain('http://en.wikipedia-on-ipfs.org.ipns.localhost:8080') // true (assuming DNSLink)
isIPFS.ipnsSubdomain('http://hostname-without-tld.ipns.dweb.link') // false (missing TLD)

@@ -112,5 +118,6 @@ isIPFS.multiaddr('/ip4/127.0.0.1/udp/1234') // true

isIPFS.peerMultiaddr('/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') // true
isIPFS.peerMultiaddr('/ip4/127.0.0.1/tcp/1234/ws/ipfs/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true
isIPFS.peerMultiaddr('/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4/p2p-circuit/ipfs/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true
isIPFS.peerMultiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') // true
isIPFS.peerMultiaddr('/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') // true (legacy notation)
isIPFS.peerMultiaddr('/ip4/127.0.0.1/tcp/1234/ws/p2p/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true
isIPFS.peerMultiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4/p2p-circuit/p2p/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true
isIPFS.peerMultiaddr('/ip4/127.0.0.1/udp/1234') // false

@@ -124,6 +131,5 @@ ```

Detection of IPFS Paths and identifiers in URLs is a two-stage process:
1. `urlPattern`/`pathPattern`/`subdomainPattern` regex is applied to quickly identify potential candidates
1. `pathPattern`/`pathGatewayPattern`/`subdomainGatewayPattern` regex is applied to quickly identify potential candidates
2. proper CID validation is applied to remove false-positives
## Content Identifiers

@@ -188,12 +194,22 @@

Returns `true` if the provided string includes a valid IPFS or IPNS subdomain or `false` otherwise.
Returns `true` if the provided `url` string includes a valid IPFS, looks like IPNS/DNSLink subdomain or `false` otherwise.
### `isIPFS.ipfsSubdomain(url)`
Returns `true` if the provided string includes a valid IPFS subdomain or `false` otherwise.
Returns `true` if the provided `url` string includes a valid IPFS subdomain (case-insensitive CIDv1) or `false` otherwise.
### `isIPFS.ipnsSubdomain(url)`
Returns `true` if the provided string includes a valid IPNS subdomain or `false` otherwise.
Returns `true` if the provided `url` string looks like a valid IPNS subdomain
(CIDv1 with `libp2p-key` multicodec or something that looks like a FQDN, for example `en.wikipedia-on-ipfs.org.ipns.localhost:8080`) or `false`
otherwise.
**Note:** `ipnsSubdomain` method works in offline mode: it does not perform
actual IPNS record lookup over DHT or other content routing method. It may
return false-positives:
- To ensure IPNS record exists, make a call to `/api/v0/name/resolve?arg=<ipnsid>`
- To ensure DNSLink exists, make a call to `/api/v0/dns?arg=<fqdn>`
## Multiaddrs

@@ -200,0 +216,0 @@

@@ -9,12 +9,17 @@ 'use strict'

const CID = require('cids')
const { URL } = require('iso-url')
const urlPattern = /^https?:\/\/[^/]+\/(ip(f|n)s)\/((\w+).*)/
const pathPattern = /^\/(ip(f|n)s)\/((\w+).*)/
const pathGatewayPattern = /^https?:\/\/[^/]+\/(ip[fn]s)\/([^/?#]+)/
const pathPattern = /^\/(ip[fn]s)\/([^/?#]+)/
const defaultProtocolMatch = 1
const defaultHashMath = 4
const defaultHashMath = 2
const fqdnPattern = /^https?:\/\/([^/]+)\.(ip(?:f|n)s)\.[^/]+/
const fqdnHashMatch = 1
const fqdnProtocolMatch = 2
// CID, libp2p-key or DNSLink
const subdomainGatewayPattern = /^https?:\/\/([^/]+)\.(ip[fn]s)\.[^/?]+/
const subdomainIdMatch = 1
const subdomainProtocolMatch = 2
// Fully qualified domain name (FQDN) that has an explicit .tld suffix
const fqdnWithTld = /^(([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])\.)+([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])$/
function isMultihash (hash) {

@@ -80,3 +85,3 @@ const formatted = convertToString(hash)

if (hash && pattern === fqdnPattern) {
if (hash && pattern === subdomainGatewayPattern) {
// when doing checks for subdomain context

@@ -105,9 +110,20 @@ // ensure hash is case-insensitive

if (hashMatch && pattern === fqdnPattern) {
let hash = match[hashMatch]
let ipnsId = match[hashMatch]
if (ipnsId && pattern === subdomainGatewayPattern) {
// when doing checks for subdomain context
// ensure hash is case-insensitive
// ensure ipnsId is case-insensitive
// (browsers force-lowercase authority compotent anyway)
hash = hash.toLowerCase()
return isCID(hash)
ipnsId = ipnsId.toLowerCase()
// Check if it is cidv1
if (isCID(ipnsId)) return true
// Check if it looks like FQDN
try {
// URL implementation in web browsers forces lowercase of the hostname
const { hostname } = new URL(`http://${ipnsId}`) // eslint-disable-line no-new
// Check if potential FQDN has an explicit TLD
return fqdnWithTld.test(hostname)
} catch (e) {
return false
}
}

@@ -134,5 +150,12 @@

const ipfsSubdomain = (url) => isIpfs(url, fqdnPattern, fqdnProtocolMatch, fqdnHashMatch)
const ipnsSubdomain = (url) => isIpns(url, fqdnPattern, fqdnProtocolMatch, fqdnHashMatch)
const ipfsSubdomain = (url) => isIpfs(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch)
const ipnsSubdomain = (url) => isIpns(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch)
const subdomain = (url) => ipfsSubdomain(url) || ipnsSubdomain(url)
const ipfsUrl = (url) => isIpfs(url, pathGatewayPattern) || ipfsSubdomain(url)
const ipnsUrl = (url) => isIpns(url, pathGatewayPattern) || ipnsSubdomain(url)
const url = (url) => ipfsUrl(url) || ipnsUrl(url) || subdomain(url)
const path = (path) => isIpfs(path, pathPattern) || isIpns(path, pathPattern)
module.exports = {

@@ -144,16 +167,16 @@ multihash: isMultihash,

base32cid: (cid) => (isMultibase(cid) === 'base32' && isCID(cid)),
ipfsSubdomain: ipfsSubdomain,
ipnsSubdomain: ipnsSubdomain,
subdomain: (url) => (ipfsSubdomain(url) || ipnsSubdomain(url)),
subdomainPattern: fqdnPattern,
ipfsUrl: (url) => isIpfs(url, urlPattern),
ipnsUrl: (url) => isIpns(url, urlPattern),
url: (url) => (isIpfs(url, urlPattern) || isIpns(url, urlPattern)),
urlPattern: urlPattern,
ipfsSubdomain,
ipnsSubdomain,
subdomain,
subdomainGatewayPattern,
ipfsUrl,
ipnsUrl,
url,
pathGatewayPattern: pathGatewayPattern,
ipfsPath: (path) => isIpfs(path, pathPattern),
ipnsPath: (path) => isIpns(path, pathPattern),
path: (path) => (isIpfs(path, pathPattern) || isIpns(path, pathPattern)),
pathPattern: pathPattern,
urlOrPath: (x) => (isIpfs(x, urlPattern) || isIpns(x, urlPattern) || isIpfs(x, pathPattern) || isIpns(x, pathPattern)),
path,
pathPattern,
urlOrPath: (x) => url(x) || path(x),
cidPath: path => isString(path) && !isCID(path) && isIpfs(`/ipfs/${path}`, pathPattern)
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc