Skip to content

Commit 7ab7125

Browse files
authored
feat(subdomain): support inlined DNSLink names (#36)
This correctly detects subdomains with DNSLink name inlined into a single DNS label. More details: ipfs/in-web-browsers#169
1 parent c25fce8 commit 7ab7125

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

src/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ function isIpns (input, pattern, protocolMatch = defaultProtocolMatch, hashMatch
115115
if (isCID(ipnsId)) return true
116116
// Check if it looks like FQDN
117117
try {
118+
if (!ipnsId.includes('.') && ipnsId.includes('-')) {
119+
// name without tld, assuming its inlined into a single DNS label
120+
// (https://github.com/ipfs/in-web-browsers/issues/169)
121+
// en-wikipedia--on--ipfs-org → en.wikipedia-on-ipfs.org
122+
ipnsId = ipnsId.replace(/--/g, '@').replace(/-/g, '.').replace(/@/g, '-')
123+
}
118124
// URL implementation in web browsers forces lowercase of the hostname
119125
const { hostname } = new URL(`http://${ipnsId}`) // eslint-disable-line no-new
120126
// Check if potential FQDN has an explicit TLD

test/test-subdomain.spec.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,18 @@ describe('ipfs subdomain', () => {
110110
done()
111111
})
112112

113-
it('isIPFS.ipnsSubdomain should not match if *.ipns is not a fqdn with tld', (done) => {
114-
const actual = isIPFS.ipnsSubdomain('http://no-fqdn-with-tld.ipns.dweb.link')
113+
it('isIPFS.ipnsSubdomain should not match if *.ipns is not a valid hostname', (done) => {
114+
const actual = isIPFS.ipnsSubdomain('http://invalid-hostname-.ipns.dweb.link')
115115
expect(actual).to.equal(false)
116116
done()
117117
})
118118

119+
it('isIPFS.ipnsSubdomain should match if *.ipns is FQDN inlined into a single DNS label', (done) => {
120+
const actual = isIPFS.ipnsSubdomain('https://en-wikipedia--on--ipfs-org.ipns.dweb.link')
121+
expect(actual).to.equal(true)
122+
done()
123+
})
124+
119125
it('isIPFS.subdomain should match an ipfs subdomain', (done) => {
120126
const actual = isIPFS.subdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link')
121127
expect(actual).to.equal(true)
@@ -148,11 +154,17 @@ describe('ipfs subdomain', () => {
148154
})
149155

150156
it('isIPFS.subdomain should not match if *.ipns is not libp2pkey nor fqdn', (done) => {
151-
const actual = isIPFS.subdomain('http://not-a-cid-or-dnslink.ipns.dweb.link')
157+
const actual = isIPFS.subdomain('http://not-a-cid-or-valid-hostname-.ipns.dweb.link')
152158
expect(actual).to.equal(false)
153159
done()
154160
})
155161

162+
it('isIPFS.subdomain should match if *.ipns looks like an inlined DNSLink name', (done) => {
163+
const actual = isIPFS.subdomain('http://en-wikipedia--on--ipfs-org.ipns.dweb.link')
164+
expect(actual).to.equal(true)
165+
done()
166+
})
167+
156168
it('isIPFS.subdomain should not match a Uint8Array data type', (done) => {
157169
const actual = isIPFS.subdomain(uint8ArrayFromString('QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR', 'base58btc'))
158170
expect(actual).to.equal(false)

0 commit comments

Comments
 (0)