From 5d6d1a2aa2fc64b61f374532c1f0766ce38725f3 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 18 Jan 2021 01:23:59 +0100 Subject: [PATCH] feat(subdomain): support inlined DNSLink names This correctly detects subdomains with DNSLink name inlined into a single DNS label. More details: https://github.com/ipfs/in-web-browsers/issues/169 License: MIT Signed-off-by: Marcin Rataj --- src/index.js | 6 ++++++ test/test-subdomain.spec.js | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index 0b09d08..9492dcb 100644 --- a/src/index.js +++ b/src/index.js @@ -115,6 +115,12 @@ function isIpns (input, pattern, protocolMatch = defaultProtocolMatch, hashMatch if (isCID(ipnsId)) return true // Check if it looks like FQDN try { + if (!ipnsId.includes('.') && ipnsId.includes('-')) { + // name without tld, assuming its inlined into a single DNS label + // (https://github.com/ipfs/in-web-browsers/issues/169) + // en-wikipedia--on--ipfs-org → en.wikipedia-on-ipfs.org + ipnsId = ipnsId.replace(/--/g, '@').replace(/-/g, '.').replace(/@/g, '-') + } // 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 diff --git a/test/test-subdomain.spec.js b/test/test-subdomain.spec.js index 0b0cc18..26fca73 100644 --- a/test/test-subdomain.spec.js +++ b/test/test-subdomain.spec.js @@ -110,12 +110,18 @@ describe('ipfs subdomain', () => { done() }) - it('isIPFS.ipnsSubdomain should not match if *.ipns is not a fqdn with tld', (done) => { - const actual = isIPFS.ipnsSubdomain('http://no-fqdn-with-tld.ipns.dweb.link') + it('isIPFS.ipnsSubdomain should not match if *.ipns is not a valid hostname', (done) => { + const actual = isIPFS.ipnsSubdomain('http://invalid-hostname-.ipns.dweb.link') expect(actual).to.equal(false) done() }) + it('isIPFS.ipnsSubdomain should match if *.ipns is FQDN inlined into a single DNS label', (done) => { + const actual = isIPFS.ipnsSubdomain('https://en-wikipedia--on--ipfs-org.ipns.dweb.link') + expect(actual).to.equal(true) + done() + }) + it('isIPFS.subdomain should match an ipfs subdomain', (done) => { const actual = isIPFS.subdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') expect(actual).to.equal(true) @@ -148,11 +154,17 @@ describe('ipfs subdomain', () => { }) it('isIPFS.subdomain should not match if *.ipns is not libp2pkey nor fqdn', (done) => { - const actual = isIPFS.subdomain('http://not-a-cid-or-dnslink.ipns.dweb.link') + const actual = isIPFS.subdomain('http://not-a-cid-or-valid-hostname-.ipns.dweb.link') expect(actual).to.equal(false) done() }) + it('isIPFS.subdomain should match if *.ipns looks like an inlined DNSLink name', (done) => { + const actual = isIPFS.subdomain('http://en-wikipedia--on--ipfs-org.ipns.dweb.link') + expect(actual).to.equal(true) + done() + }) + it('isIPFS.subdomain should not match a Uint8Array data type', (done) => { const actual = isIPFS.subdomain(uint8ArrayFromString('QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR', 'base58btc')) expect(actual).to.equal(false)