Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add validation of CID in Subdomains #20

Merged
merged 7 commits into from
Jul 23, 2018
Merged

Add validation of CID in Subdomains #20

merged 7 commits into from
Jul 23, 2018

Conversation

lidel
Copy link
Member

@lidel lidel commented Jul 22, 2018

(Parent issues: ipfs/ipfs-companion#526, ipfs/in-web-browsers#89, https://github.com/ipfs/ipfs/issues/337)

This PR adds below utility methods:

isIPFS.multibase('bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va') // 'base32'
isIPFS.multibase('zdj7WWeQ43G6JJvLWQWZpyHuAMq6uYWRjkBXFad11vE2LHhQ7') // 'base58btc'
isIPFS.multibase('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false (no multibase prefix in CIDv0)
isIPFS.multibase('noop') // false

isIPFS.base32cid('bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va') // true
isIPFS.base32cid('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false

isIPFS.subdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.ipns.dweb.link') // true
isIPFS.subdomain('http://www.bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // false
isIPFS.subdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.dweb.link') // false

isIPFS.ipfsSubdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true
isIPFS.ipfsSubdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.dweb.link') // false

isIPFS.ipnsSubdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.ipns.dweb.link') // true
isIPFS.ipnsSubdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.dweb.link') // false
isIPFS.ipnsSubdomain('http://QmcNioXSC1bfJj1dcFErhUfyjFzoX2HodkRccsFFVJJvg8.ipns.dweb.link') // false
isIPFS.ipnsSubdomain('http://foo-bar.ipns.dweb.link') // false (not a PeerID)
  • Closes Detect CID in Subdomains #19 (and Closes Should be part of the IPFS org + needs a Lead Maintainer + needs to have Jenkins run. #17)
  • Subdomain validation follows FQDN convention of cidv1b32.ip(f|n)s.domain.tld suggested in Detect CID in subdomains ipfs/ipfs-companion#526 (comment)
  • IPNS support is limited to PeerID represented as cidv1b32
    • (not sure how to represent dnslink, reverse notation makes little sense, so we don't allow it in subdomains for now)
  • Subdomain checks are not included in already existing isIPFS.url on purpose.
    People already use it and we don't want to change its meaning, because isIPFS.url == true means it is safe to take URLs pathname as-is, which is not the case when subdomain is used.
  • I think we will have a separate isIPFS.nativeUrl for ipfs:// for the same reason
    • .. and a catch-all check (path || url || subdomain || nativeUrl) could be named isIPFS.any

cc @lgierth @kyledrake – thoughts?
(We need this for Companion to support cidv1b32 and subdomains, and I want to ship it before DWEB)

@lidel lidel requested a review from a user July 22, 2018 22:02
@lidel lidel requested review from alanshaw, fsdiogo and olizilla July 22, 2018 22:06
Copy link
Member

@alanshaw alanshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super cool. Really nice to see this module getting some ❤️

README.md Outdated
isIPFS.multibase('bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va') // 'base32'
isIPFS.multibase('zdj7WWeQ43G6JJvLWQWZpyHuAMq6uYWRjkBXFad11vE2LHhQ7') // 'base58btc'
isIPFS.multibase('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false (no multibase prefix in CIDv0)
isIPFS.multibase('noop') // false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels out of place to me. The rest of the API returns true/false. This is a simple call-through to multibase.isEncoded.

Copy link
Member Author

@lidel lidel Jul 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be changed to true/false or just removed? Not sure how useful it is, maybe just remove it?
(I think I've added it only because isIPFS.base32cid introduced multibase as a dependency)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I'd remove it. I considered that isIPFS.base32cid uses multibase as a dependency, and was thinking of suggesting to check like:

typeof cid === 'string' && cid.slice(0, 4) === 'bafy' && isCID(cid)

...but js-cid depends on multibase so you're not saving any bundle bytes by depending on it and using it.

README.md Outdated
@@ -71,29 +82,52 @@ isIPFS.ipfsPath('/ipfs/invalid-hash') // false

isIPFS.ipnsPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false
isIPFS.ipnsPath('/ipns/github.com') // true

isIPFS.subdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.ipns.dweb.link') // true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this true for http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link also? Maybe add an example here :D

@lidel lidel force-pushed the feat/subdomains branch from 4923789 to 8e05326 Compare July 23, 2018 10:25
@lidel lidel changed the title Add validation of Multibase prefix and CID in Subdomains Add validation of CID in Subdomains Jul 23, 2018
@lidel
Copy link
Member Author

lidel commented Jul 23, 2018

@alanshaw removed multibase, Jenkins works as expected. Ok to merge?

@@ -2,22 +2,37 @@

const base58 = require('bs58')
const multihash = require('multihashes')
const multibase = require('multibase')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still depend directly on multibase - it should be in dependencies

README.md Outdated
## API
# API

A suite of util methods provides efficient validation.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...that provides...

src/index.js Outdated
base32cid: (cid) => (isMultibase(cid) === 'base32' && isCID(cid)),
ipfsSubdomain: (url) => isIpfs(url, fqdnPattern, fqdnProtocolMatch, fqdnHashMatch),
ipnsSubdomain: (url) => isIpns(url, fqdnPattern, fqdnProtocolMatch, fqdnHashMatch),
subdomain: (url) => (isIpfs(url, fqdnPattern, fqdnProtocolMatch, fqdnHashMatch) || isIpns(url, fqdnPattern, fqdnProtocolMatch, fqdnHashMatch)),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you're calling (ipfsSubdomain || ipnsSubdomain), you should declare them before the module.exports. That way if any of those change, you won't need to change that code in two places.

To make things clearer:

const ipfsSubdomain = (url) => isIpfs(url, fqdnPattern, fqdnProtocolMatch, fqdnHashMatch)
const ipnsSubdomain = (url) => isIpns(url, fqdnPattern, fqdnProtocolMatch, fqdnHashMatch)

module.exports = {
	multihash: isMultihash,
	cid: isCID,
	base32cid: (cid) => (isMultibase(cid) === 'base32' && isCID(cid)),
	ipfsSubdomain: ipfsSubdomain,
	ipnsSubdomain: ipnsSubdomain,
	subdomain: (url) => (ipfsSubdomain(url) || ipnsSubdomain(url)),
	...
}

@lidel lidel merged commit 8b3214d into master Jul 23, 2018
@lidel lidel deleted the feat/subdomains branch July 23, 2018 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants