diff --git a/add-on/src/lib/ipfs-proxy/pre-acl.js b/add-on/src/lib/ipfs-proxy/pre-acl.js index 990a0e4a8..3061d1285 100644 --- a/add-on/src/lib/ipfs-proxy/pre-acl.js +++ b/add-on/src/lib/ipfs-proxy/pre-acl.js @@ -21,7 +21,11 @@ function createPreAcl (permission, getState, getScope, accessControl, requestAcc access = await accessControl.setAccess(scope, wildcard ? '*' : permission, allow) } - if (!access.allow) throw new Error(`User denied access to ${permission}`) + if (!access.allow) { + const err = new Error(`User denied access to ${permission}`) + err.output = { payload: { isIpfsProxyAclError: true, permission, scope } } + throw err + } return args } diff --git a/add-on/src/lib/ipfs-proxy/pre-mfs-scope.js b/add-on/src/lib/ipfs-proxy/pre-mfs-scope.js index f8af1e341..e04315c20 100644 --- a/add-on/src/lib/ipfs-proxy/pre-mfs-scope.js +++ b/add-on/src/lib/ipfs-proxy/pre-mfs-scope.js @@ -1,4 +1,5 @@ -const Path = require('path') +// Use path-browserify for consistent behavior between browser and tests on Windows +const Path = require('path-browserify') const DEFAULT_ROOT_PATH = '/dapps' // Creates a "pre" function that is called prior to calling a real function diff --git a/add-on/src/lib/ipfs-proxy/request-access.js b/add-on/src/lib/ipfs-proxy/request-access.js index 5f3a99667..d9f2b0e74 100644 --- a/add-on/src/lib/ipfs-proxy/request-access.js +++ b/add-on/src/lib/ipfs-proxy/request-access.js @@ -98,7 +98,9 @@ function createRequestAccess (browser, screen) { const userTabRemoved = new Promise((resolve, reject) => { onTabRemoved = (id) => { if (id !== tabId) return - reject(new Error(`Failed to obtain access response for ${permission} at ${scope}`)) + const err = new Error(`Failed to obtain access response for ${permission} at ${scope}`) + err.output = { payload: { isIpfsProxyAclError: true, scope, permission } } + reject(err) } browser.tabs.onRemoved.addListener(onTabRemoved) }) diff --git a/docs/window.ipfs.md b/docs/window.ipfs.md index 767b5697b..cc4efd0be 100644 --- a/docs/window.ipfs.md +++ b/docs/window.ipfs.md @@ -38,19 +38,19 @@ if (window.ipfs) { To add and get content, you could do something like this: ```js -if (window.ipfs) { +if (window.ipfs) { try { - await ipfs.add(Buffer.from('=^.^=')) - } catch (err) { - if (err.message === 'User denied access to ipfs.files.add') { - // Fallback - } else { - throw err - } - } - - const data = await ipfs.cat('QmS5RzFV9v4fucVtjATPxoxABgEmNhhduykzUbQeGyyS3N') - console.log(data.toString()) // =^.^= + const [{ hash }] = await ipfs.add(Buffer.from('=^.^=')) + const data = await ipfs.cat(hash) + console.log(data.toString()) // =^.^= + } catch (err) { + if (err.isIpfsProxyAclError) { + // Fallback + console.log('Unable to get ACL decision from user :(', err) + } else { + throw err + } + } } else { // Fallback } diff --git a/package.json b/package.json index 115eea6ab..36bd49c76 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "watch:content-scripts:ipfs-proxy:page": "watchify -p prundupify -t [ browserify-package-json --global ] add-on/src/contentScripts/ipfs-proxy/page.js -o add-on/dist/contentScripts/ipfs-proxy/page.js -v", "watch:content-scripts:ipfs-proxy:content": "nodemon --exec \"browserify -p prundupify -t brfs -t [ browserify-package-json --global ] -s IpfsProxyContent add-on/src/contentScripts/ipfs-proxy/content.js -o add-on/dist/contentScripts/ipfs-proxy/content.js -v\" --watch add-on/src/contentScripts/ipfs-proxy/content.js --watch add-on/dist/contentScripts/ipfs-proxy/page.js", "test": "run-s test:*", - "test:functional": " nyc --reporter=lcov --reporter=text mocha --timeout 15000 --require ignore-styles --reporter mocha-jenkins-reporter 'test/functional/**/*.test.js'", + "test:functional": " nyc --reporter=lcov --reporter=text mocha --timeout 15000 --require ignore-styles --reporter mocha-jenkins-reporter \"test/functional/**/*.test.js\"", "lint": "run-s lint:*", "lint:standard": "standard -v \"add-on/src/**/*.js\" \"test/**/*.js\"", "lint:web-ext": "web-ext lint", @@ -101,6 +101,7 @@ "lru_map": "0.3.3", "mime-types": "2.1.18", "p-queue": "2.4.0", + "path-browserify": "0.0.0", "piggybacker": "2.0.0", "prundupify": "1.0.0", "tachyons": "4.9.1", diff --git a/test/functional/lib/ipfs-proxy/pre-acl.test.js b/test/functional/lib/ipfs-proxy/pre-acl.test.js index 1a9ee00d8..faba83f0c 100644 --- a/test/functional/lib/ipfs-proxy/pre-acl.test.js +++ b/test/functional/lib/ipfs-proxy/pre-acl.test.js @@ -117,6 +117,29 @@ describe('lib/ipfs-proxy/pre-acl', () => { expect(() => { if (error) throw error }).to.throw(`User denied access to ${permission}`) }) + it('should have a well-formed Error if denied', async () => { + const getState = () => ({ ipfsProxy: true }) + const accessControl = new AccessControl(new Storage()) + const getScope = () => 'https://ipfs.io/' + const permission = 'files.add' + const requestAccess = Sinon.spy(async () => ({ allow: false })) + const preAcl = createPreAcl(permission, getState, getScope, accessControl, requestAccess) + + let error + + try { + await preAcl() + } catch (err) { + error = err + } + + expect(error.output.payload).to.deep.eql({ + isIpfsProxyAclError: true, + permission, + scope: getScope() + }) + }) + it('should not re-request if allowed', async () => { const getState = () => ({ ipfsProxy: true }) const accessControl = new AccessControl(new Storage()) diff --git a/yarn.lock b/yarn.lock index 0c3f7278f..43ec641ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7176,7 +7176,7 @@ pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" -path-browserify@~0.0.0: +path-browserify@0.0.0, path-browserify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a"