ipfs / ipfs-companion

Browser extension that simplifies access to IPFS resources on the web
https://docs.ipfs.tech/install/ipfs-companion/
Creative Commons Zero v1.0 Universal
2.05k stars 325 forks source link

Allow web apps to request pin of files or even a general permission to pin. #981

Open felixniemeyer opened 3 years ago

felixniemeyer commented 3 years ago

Is your feature request related to a problem? Please describe. I'm writing a web app which stores user data (e.g. text articles) on ipfs. Therefore I'm running a local ipfs-js node in the web app. But when the user closes the tab, the browser ipfs node shuts down and added files are barely accessible. From the web app code I would like to ask the ipfs companion to add a certain content (by cid or arraybuffer) to the local ipfs node.

Describe the solution you'd like I imagine ipfs companion could provide an ipfsCompanion object into the JS scope similarly like Metamask provides the web3 context. I could then do ipfsCompanion.add(cid). ipfs companion would ask the user - "hey, this web app wants to pin that (size: xx kB)" and then add it upon user confirmation. Ipfs companion may even ask the the user "do you want to permit apps from < host > to add files to your local ipfs node in general?". If the user consents, future add requests would be permitted automatically.

The ipfs companion could expose the full ipfs js api to web apps this way. I also thought about the ipfs pinning API (I'm not very familiar with it) but maybe that's enough for the ipfs companion to expose for now.

If this is in scope of the ipfs companion extension I could help with development.

welcome[bot] commented 3 years ago

Thank you for submitting your first issue to this repository! A maintainer will be here shortly to triage and review. In the meantime, please double-check that you have provided all the necessary information to make this process easy! Any information that can help save additional round trips is useful! We currently aim to give initial feedback within two business days. If this does not happen, feel free to leave a comment. Please keep an eye on how this issue will be labeled, as labels give an overview of priorities, assignments and additional actions requested by the maintainers:

Finally, remember to use https://discuss.ipfs.io if you just need general support.

lidel commented 3 years ago

This sounds related to a wider discussion about node reuse and resource sharing on the web (https://github.com/ipfs/in-web-browsers/issues/158), but I'll focus on "exposing IPFS API on web pages" below.

On past experiments

We did some window.ipfs experiments in the past, and it worked exactly like you described (see docs) but it caused more problems than it has solved.

As noted in https://github.com/ipfs-shipyard/ipfs-companion/issues/589#issuecomment-712356448:

The window.ipfs experiment was disabled since last year (see #777 for rationale why).

It did help us understand challenges and risks, and identified the need for more robust API for the web. We are officially putting window.ipfs experiment (in the form that was disabled in #777) in the Icebox and will be looking at other ways for node sharing and deduplication on the web in https://github.com/ipfs/in-web-browsers/issues/158.

If we revisit this approach, it will be a more robust API tailored for use on the web, and most likely happen after migration to Manifest V3 (#666).

If we bring something like this back, and expect web developers to use it, it must be future-proof, so would have to be a dedicated API independent of js-ipfs.

Opportunity to explore native APIs in browsers like Brave

Something we could explore is exposing some sort of window.ipfs in Brave but only when page is loaded over ipfs:// or ipns://. For sure we do not want to expose the same API as /api/v0 in go-ipfs, as it was never designed to be exposed to webpages. We would need something dedicated.

Personally I believe in "no API is the best API" mantra, so instead of having window.ipfs for basic add I'd like us to explore "native" interactions like:

const { cid } = await fetch('ipfs://cid', { method: 'POST' }), body: data).json()

This is just an idea, but we may start experimenting with this type of "no library" approach on HTTP Gateways soon (https://github.com/protocol/web3-dev-team/pull/1).

On user agency

My main worry around is that user agency is often glossed over behind "there should be popup and user will decide" and web3 users are essentially living in Microsoft Windows UAC hell where they are blindly trained to accept every access control popup and at the end of the day there is a decrease of security because the burden of opsec was shifted onto user who has limited decision-making budget every day. Ideally there should be no popup unless a permanent persistence is required, and things should be automatically sandboxed for each origin based on Origin and Referer headers. Figuring out the details in a way that does not compromise privacy by enabling "supercookies" is the biggest challenge here.

Gathering feedback

@felixniemeyer Is add and (remote) pinning the only need you have? Do you see anything else you'd like to do in the future?

The list usually starts with "I want add and pin commands" and then people quickly request origin-sandboxed MFS and other features around the existing API.

I'd like to understand most common use cases better and design user journey end-to end, and then think about developer apis. For example, what is the value of local pinning if the user closes the laptop and both nodes disappear? Can we improve setup of remote pinning service so no API key copying is necessary, and it feels more like granting oauth2 permission (https://github.com/ipfs/pinning-services-api-spec/issues/34)? etc

I'd love to hear your thought on this (and don't feel constrained by existing APIs, lmk what "ideal" world would look like) :pray:

SionoiS commented 3 years ago

I'm in a similar boat but with a more complex use case. I have built a web-app that can do live streaming on IPFS.

It require access to a IPFS node with; ipfs pubsub pub (live chat),ipfs pubsub sub (live chat & video), ipfs dag get, ipfs cat and ipfs name resolve.

Currently in brave using the fetch API is equivalent to ipfs cat and it's not enough. I can't ask users to allow CORS in their IPFS node like I do for my dev needs.

Security is a big concern but also privacy. How do we prevent website from snooping around for specific CIDs on the user's node or how to prevent website from running malicious code fetched from ipfs.

Baseline for me is no user interaction required, unfortunately we're far from that at the moment. I wish I knew more about browser and web stuff so that I could help...