Skip to content
This repository has been archived by the owner on Oct 16, 2020. It is now read-only.

Commit

Permalink
feat: allow urls with authentication (#28)
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Henrique Dias <hacdias@gmail.com>
  • Loading branch information
hacdias committed Nov 4, 2019
1 parent c536104 commit b947b1a
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 17 deletions.
19 changes: 3 additions & 16 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

const root = require('window-or-global')
const IpfsApi = require('ipfs-http-client')
const multiaddr = require('multiaddr')
const tryCompanion = require('./companion')
const tryWindow = require('./window.ipfs')
const tryApi = require('./js-ipfs-api')
const tryJsIpfs = require('./js-ipfs')
const { isURL, isMultiaddress } = require('./utils')

const defaultOptions = {
tryWindow: true,
Expand Down Expand Up @@ -151,7 +151,7 @@ async function getIpfs (opts, { store, getState, dispatch }) {
}
}
if (opts.tryApi) {
const { apiAddress, defaultApiAddress } = getState().ipfs
let { apiAddress, defaultApiAddress } = getState().ipfs
const { location } = root
const res = await tryApi({ apiAddress, defaultApiAddress, location, IpfsApi, ipfsConnectionTest })
if (res) {
Expand All @@ -169,19 +169,6 @@ async function getIpfs (opts, { store, getState, dispatch }) {
dispatch({ type: 'IPFS_INIT_FAILED' })
}

function isMultiaddress (addr) {
if (addr === null || addr === undefined || typeof addr === 'undefined') {
return false
}

try {
multiaddr(addr)
return true
} catch (_) {
return false
}
}

function getUserOpts (key) {
let userOpts = null
if (root.localStorage) {
Expand Down Expand Up @@ -214,7 +201,7 @@ function saveUserOpts (key, val) {

function getUserProvidedIpfsApi () {
const ipfsApi = getUserOpts('ipfsApi')
if (ipfsApi && !isMultiaddress(ipfsApi)) {
if (ipfsApi && !isMultiaddress(ipfsApi) && !isURL(ipfsApi)) {
console.warn(`The ipfsApi address ${ipfsApi} is invalid.`)
return null
}
Expand Down
23 changes: 22 additions & 1 deletion src/js-ipfs-api/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/* eslint-env browser, webextensions */
const toMultiaddr = require('uri-to-multiaddr')
const { isURL } = require('../utils')
const provider = 'js-ipfs-api'

// 1. Try user specified API address
Expand Down Expand Up @@ -41,13 +43,32 @@ async function tryApi ({ IpfsApi, apiAddress, defaultApiAddress, location, ipfsC

// Helper to construct and test an api client. Returns an js-ipfs-api instance or null
async function maybeApi ({ apiAddress, apiOpts, ipfsConnectionTest, IpfsApi }) {
const address = isURL(apiAddress) ? parseURL(apiAddress) : apiAddress

try {
const ipfs = new IpfsApi(apiAddress, apiOpts)
const ipfs = new IpfsApi(address, apiOpts)
await ipfsConnectionTest(ipfs)
return { ipfs, provider, apiAddress }
} catch (error) {
console.log('Failed to connect to ipfs-api', apiAddress)
}
}

function parseURL (addr) {
const url = new URL(addr)

const opts = {
host: url.hostname,
port: url.port,
protocol: url.protocol.slice(0, -1),
headers: {}
}

if (url.username) {
opts.headers.authorization = `Basic ${btoa(unescape(encodeURIComponent(url.username + ':' + url.password)))}`
}

return opts
}

module.exports = tryApi
38 changes: 38 additions & 0 deletions src/js-ipfs-api/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,41 @@ it('Should use the defaultApiAddress if location fails', async (done) => {
expect(config.protocol).toEqual('http')
done()
})

it('Should use the apiAddress (url)', async (done) => {
const opts = {
apiAddress: 'http://1.1.1.1:1111',
defaultApiAddress: '/ip4/127.0.0.1/tcp/5001',
location: new URL('http://localhost:5001'),
IpfsApi: IpfsApi,
ipfsConnectionTest: jest.fn().mockResolvedValueOnce(true)
}
const res = await tryApi(opts)
expect(res.apiAddress).toEqual(opts.apiAddress)
expect(res.provider).toEqual('js-ipfs-api')
expect(opts.ipfsConnectionTest.mock.calls.length).toBe(1)
const config = res.ipfs.getEndpointConfig()
expect(config.host).toEqual('1.1.1.1')
expect(config.port).toEqual('1111')
expect(config.protocol).toEqual('http')
done()
})

it('Should use the apiAddress (url with basic auth)', async (done) => {
const opts = {
apiAddress: 'http://user:pass@1.1.1.1:1111',
defaultApiAddress: '/ip4/127.0.0.1/tcp/5001',
location: new URL('http://localhost:5001'),
IpfsApi: IpfsApi,
ipfsConnectionTest: jest.fn().mockResolvedValueOnce(true)
}
const res = await tryApi(opts)
expect(res.apiAddress).toEqual(opts.apiAddress)
expect(res.provider).toEqual('js-ipfs-api')
expect(opts.ipfsConnectionTest.mock.calls.length).toBe(1)
const config = res.ipfs.getEndpointConfig()
expect(config.host).toEqual('1.1.1.1')
expect(config.port).toEqual('1111')
expect(config.protocol).toEqual('http')
done()
})
32 changes: 32 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict'
/* eslint-env browser, webextensions */

const multiaddr = require('multiaddr')

function isMultiaddress (addr) {
if (addr === null || addr === undefined || typeof addr === 'undefined') {
return false
}

try {
multiaddr(addr)
return true
} catch (_) {
return false
}
}

function isURL (addr) {
try {
// eslint-disable-next-line
new URL(addr)
return true
} catch (e) {
return false
}
}

module.exports = {
isMultiaddress,
isURL
}

0 comments on commit b947b1a

Please sign in to comment.