Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Epic: WebExtension with pluggable IPFS nodes #39

Open
flyingzumwalt opened this issue Feb 15, 2017 · 16 comments
Open

Epic: WebExtension with pluggable IPFS nodes #39

flyingzumwalt opened this issue Feb 15, 2017 · 16 comments
Assignees
Labels

Comments

@flyingzumwalt
Copy link
Contributor

Break up the functionality that #12 is aiming for.

@flyingzumwalt
Copy link
Contributor Author

flyingzumwalt commented Feb 15, 2017

How we're going to break it up (will make issues):

General notes:

Stories:

If A is completely done, B and C can be activated with a toggle -- Redirect-URLs can be true or false

@flyingzumwalt flyingzumwalt changed the title Break up #12 Epic: Web Extension supports gateways and core api with both js and go nodes Feb 15, 2017
@flyingzumwalt
Copy link
Contributor Author

See #43 for a discussion of the security implications of this web extension.

@victorb
Copy link
Member

victorb commented Feb 21, 2017

I've did some quick research after thinking that probably we can't expose anything on window from an web extension to a web page. And yeah, we can't just add whatever we want to a page's window object.

What we can do is to setup some message passing and provide a library for websites to use that.

But, we won't be able to have an extension that people can simply install and now window.ipfs exists everywhere as a full node... There will have to be things that the website authors needs to do.

@Kubuxu
Copy link
Member

Kubuxu commented Feb 21, 2017

We for sure can add an element that could load a script and then use some sort of RPC (or ipfs api) to pass the messages.

Just an idea.

@victorb
Copy link
Member

victorb commented Feb 21, 2017

@Kubuxu you won't be able to load arbitrary scripts into the same context of a web page. CSP will deny that and it would be a security threat otherwise.

This RPC/ipfs-api you're talking about, is a possibility, but the website authors needs themselves to include this in their webpage. That's not what we're aiming for, but rather be able to provide everything so a user could simply do window.ipfs.swarm.peers(cb) without any further fuzz.

@Kubuxu
Copy link
Member

Kubuxu commented Feb 21, 2017

Can't you modify the webpage as it is loaded to include inline script block that would contain the script necessary to expose the bindings?

@Kubuxu
Copy link
Member

Kubuxu commented Feb 21, 2017

@victorb
Copy link
Member

victorb commented Feb 21, 2017

@Kubuxu as far as my testing went, no. The browser rejects to execute any code that has been injected into the page. I can successfully run a js-ipfs node in the background page, and communicate with it via a content script, but can't expose a API for the communication...

@Kubuxu
Copy link
Member

Kubuxu commented Feb 21, 2017

I can successfully run a js-ipfs node in the background page, and communicate with it via a content script, but can't expose a API for the communication...

I don't understand the "but can't expose a API for the communication..." part.

@victorb
Copy link
Member

victorb commented Feb 21, 2017

Yeah, what I did was setting up a background page that has the daemon running and exposes a couple of methods via message passing.

In the content script, I can successfully add properties to the window object of a page. I can also talk with the background ipfs daemon without troubles.

Problems arise when I wanted to write a thin-layer of API methods that the users can use directly from their page. I'm adding functions to a IPFS object that acts kind of like js-ipfs-api, but the browser won't execute those functions, since they were added from the outside.

I've made the code public here: https://github.com/VictorBjelkholm/js-ipfs-in-the-browser

Content-Script: https://github.com/VictorBjelkholm/js-ipfs-in-the-browser/blob/master/page-script.js
Background-Script: https://github.com/VictorBjelkholm/js-ipfs-in-the-browser/blob/master/start-daemon.js

I don't understand the "but can't expose a API for the communication..." part.

We can't have window.ipfs that just works. Users are required to include something for the communication to the daemon...

@Kubuxu
Copy link
Member

Kubuxu commented Feb 21, 2017

I think we need to use cloneInto as it is shown here: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts#cloneInto

@flyingzumwalt
Copy link
Contributor Author

Maybe it's a bad idea for the extension to initialize window.ipfs anyway. Wouldn't it be better if we allow web pages to initialize that with a very small amount of code -- so the browser extension provides the whole ipfs stack and a web developer just has to initialize the connection wherever they see fit?

Either way, any page that wants to use ipfs is going to have to run a script to check if the extension is installed, so we will need to provide an easy way to do the following (and should provide an npm module that does it for you):

  1. Check if the ipfs web extension is installed
  2. Initialize ipfs
    2a. If the web extension is installed, just initialize the connection
    2b. If the web extension is not installed, download ipfs and then initialize

Given that, is it really necessary for the web extension to initialize window.ipfs?

@victorb
Copy link
Member

victorb commented Feb 21, 2017

We wanted to simulate an environment which would be as similar as possible to when we actually have ipfs supported natively in the browsers. We could do bunch of guesses how that would look, but probably there would be an node of some sort exposed at window.ipfs. It's straight-forward to check if it exists.

if (window.ipfs === undefined) {
 // ipfs is not here, we need to have a polyfill
} else {
 // ipfs was on the page already!
}

This is also how new features are being detected in browsers, and polyfill if necessary...

I think something that is missed, is the performance gain of having an already initialized node as well. Currently, js-ipfs when starting up in the browser, locks my browser for half a second and takes a while to find peers.

If we could run the node always, and allow pages to directly connect to it, we'll have no startup time + already connected peers when the page first loads.

@flyingzumwalt
Copy link
Contributor Author

Those are all good points. Thanks for clarifying.

@ghost ghost removed the status/in-progress In progress label Mar 28, 2017
@ghost ghost changed the title Epic: Web Extension supports gateways and core api with both js and go nodes Epic: WebExtension with pluggable IPFS nodes Apr 18, 2017
@ghost ghost added the epic label Apr 18, 2017
@jmc265
Copy link

jmc265 commented Jul 10, 2017

Potential solution for the issue around content scripts not being able to affect the page script's window object:

From the content script, inject a script ('js-ipfs-bridge.js') into the page (using the method detailed here: https://gist.github.com/nok/a98c7c5ce0d0803b42da50c4b901ef84).

'js-ipfs-bridge.js' can then define a window.ipfs shim which just uses window.postMessage to communicate back and forth between the page scripts and the content scripts.

This means that developers can just go ahead and use window.ipfs unaware that the extension has re-mapped that object to the extension's content and background scripts via postMessage.

@daviddias
Copy link
Member

All the extension work is happening here https://github.com/ipfs/ipfs-companion

@daviddias daviddias added the status/ready Ready to be worked label Dec 13, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants