Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
findDNSLinkHostname (url) {
const { hostname, pathname } = new URL(url)
// check //foo.tld/ipns/
if (IsIpfs.ipnsPath(pathname)) {
// we may have false-positives here, so we do additional checks below
const ipnsRoot = pathname.match(/^\/ipns\/([^/]+)/)[1]
// console.log('findDNSLinkHostname ==> inspecting IPNS root', ipnsRoot)
// Ignore PeerIDs, match DNSLink only
if (!IsIpfs.cid(ipnsRoot) && dnslinkResolver.readAndCacheDnslink(ipnsRoot)) {
// console.log('findDNSLinkHostname ==> found DNSLink for FQDN in url.pathname: ', ipnsRoot)
return ipnsRoot
}
}
// check ///foo/bar
if (dnslinkResolver.readAndCacheDnslink(hostname)) {
// console.log('findDNSLinkHostname ==> found DNSLink for url.hostname', hostname)
return hostname
}
}
const resolve = async (name, opts) => {
opts = opts || {}
if (!isIpfs.path(name)) {
throw new Error('invalid argument ' + name)
}
if (isIpfs.ipnsPath(name)) {
name = await ipfs.name.resolve(name, opts)
}
const [, , hash, ...rest] = name.split('/') // ['', 'ipfs', 'hash', ...path]
const cid = new CID(hash)
// nothing to resolve return the input
if (rest.length === 0) {
return `/ipfs/${cidToString(cid, { base: opts.cidBase })}`
}
const path = rest.join('/')
const results = ipfs._ipld.resolve(cid, path)
let value = cid
let remainderPath = path
function validIpnsPath (path, dnsLink) {
if (IsIpfs.ipnsPath(path)) {
// we may have false-positives here, so we do additional checks below
const ipnsRoot = path.match(/^\/ipns\/([^/]+)/)[1]
// console.log('==> IPNS root', ipnsRoot)
// first check if root is a regular CID
if (IsIpfs.cid(ipnsRoot)) {
// console.log('==> IPNS is a valid CID', ipnsRoot)
return true
}
// then see if there is an DNSLink entry for 'ipnsRoot' hostname
// TODO: use dnslink cache only
if (dnsLink.readAndCacheDnslink(ipnsRoot)) {
// console.log('==> IPNS for FQDN with valid dnslink: ', ipnsRoot)
return true
}
}
return false
async resolveToImmutableIpfsPath (urlOrPath) {
const path = ipfsPathValidator.resolveToIpfsPath(urlOrPath)
// Fail fast if no IPFS Path
if (!path) return null
// Resolve /ipns/ → /ipfs/
if (IsIpfs.ipnsPath(path)) {
const labels = path.split('/')
// We resolve /ipns/ as value in DNSLink cache may be out of date
const ipnsRoot = `/ipns/${labels[2]}`
// js-ipfs v0.34 does not support DNSLinks in ipfs.name.resolve: https://github.com/ipfs/js-ipfs/issues/1918
// TODO: remove ipfsNameResolveWithDnslinkFallback when js-ipfs implements DNSLink support in ipfs.name.resolve
const ipfsNameResolveWithDnslinkFallback = async (resolve) => {
try {
return await resolve()
} catch (err) {
const fqdn = ipnsRoot.replace(/^.*\/ipns\/([^/]+).*/, '$1')
if (err.message === 'Non-base58 character' && isFQDN(fqdn)) {
// js-ipfs without dnslink support, fallback to the value read from DNSLink
const dnslink = dnslinkResolver.readAndCacheDnslink(fqdn)
if (dnslink) {
// swap problematic /ipns/{fqdn} with /ipfs/{cid} and retry lookup
const resolvePath = (ipfsNode, name) => {
// ipns path
if (isIPFS.ipnsPath(name)) {
log(`resolve ipns path ${name}`)
return ipfsNode._ipns.resolve(name)
}
// ipfs path
return ipfsNode.dag.get(name.substring('/ipfs/'.length))
}
// First: Check if dnslink heuristic yields any results
// Note: this depends on which dnslink lookup policy is selecten in Preferences
if (state.dnslinkRedirect && state.dnslinkPolicy && dnslinkResolver.canLookupURL(request.url)) {
// x-ipfs-path is a strong indicator of IPFS support
// so we force dnslink lookup to pre-populate dnslink cache
// in a way that works even when state.dnslinkPolicy !== 'enabled'
// All the following requests will be upgraded to IPNS
const cachedDnslink = dnslinkResolver.readAndCacheDnslink(new URL(request.url).hostname)
const dnslinkRedirect = dnslinkResolver.dnslinkRedirect(request.url, cachedDnslink)
if (dnslinkRedirect) {
log(`onHeadersReceived: dnslinkRedirect from ${request.url} to ${dnslinkRedirect.redirectUrl}`)
return dnslinkRedirect
}
}
// Additional validation of X-Ipfs-Path
if (IsIpfs.ipnsPath(xIpfsPath)) {
// Ignore unhandled IPNS path by this point
// (means DNSLink is disabled so we don't want to make a redirect that works like DNSLink)
// log(`onHeadersReceived: ignoring x-ipfs-path=${xIpfsPath} (dnslinkRedirect=false, dnslinkPolicy=false or missing DNS TXT record)`)
} else if (IsIpfs.ipfsPath(xIpfsPath)) {
// It is possible that someone exposed /ipfs// under /
// and our path-based onBeforeRequest heuristics were unable
// to identify request as IPFS one until onHeadersReceived revealed
// presence of x-ipfs-path header.
// Solution: convert header value to a path at public gateway
// (optional redirect to custom one can happen later)
const url = new URL(request.url)
const pathWithArgs = `${xIpfsPath}${url.search}${url.hash}`
const newUrl = pathAtHttpGateway(pathWithArgs, state.pubGwURLString)
// redirect only if anything changed
if (newUrl !== request.url) {
log(`onHeadersReceived: normalized ${request.url} to ${newUrl}`)