lbryio / lbry-desktop

A browser and wallet for LBRY, the decentralized, user-controlled content marketplace.
https://lbry.tech
MIT License
3.56k stars 414 forks source link

Embedded applications api #2590

Open btzr-io opened 5 years ago

btzr-io commented 5 years ago

Actual Behavior

The app allows you to embed applications such as games with the lbry-package format, but they are just isolated static websites and can't take advantage of the lbry-sdk.

Expected Behavior

I don't exactly sure what should be the expected behavior, that's why I'm opening this issue to discuss this feature...

If you have some ideas or thoughts on this feel free to leave a comment.

Suggested Solutions

Create an api that works like a bridge between the lbry-desktop app and the lbry-package app:

This is possible to achieve with a preload script attached to the webview:

When disabling Node.js integration, you can still expose APIs to your website that do consume Node.js modules or features. Preload scripts continue to have access to require and other Node.js features, allowing developers to expose a custom API to remotely loaded content.

https://github.com/electron/electron/blob/master/docs/tutorial/security.md#2-do-not-enable-nodejs-integration-for-remote-content

Example

MyApp.lbry-package/index.html

<script>
    // Accessible from window.LBRY_BRIDGE ( no need to install or do any magic tricks ) 
    button.onClick = () => LBRY_BRIDGE.doSomething("Purchase a claim or send a transaction!");
</script>

Simple app handler

onDoSomething(e) => {
  // Request for permission
  const granted = requestAccess();
  if (granted) {
     // Continue and notify success...
    success();
  } else {
    // User blocked the request...
    cancel();
  }
}
EnigmaCurry commented 5 years ago

So I played with embedded apps a few months ago (not sure how much has changed since) and I was disappointed that the app was just a small window inside the lbry-desktop app and no ability to fullscreen, and no ability to multi-task inside lbry-desktop. This got me to thinking that it would be nice if external (non-electron) apps could interact with some sort of lbry-desktop api.

Instead of using window.LBRY_BRIDGE, which would limit access to only electron, I am wondering if an REST API listening on a port would be more flexible. I believe you can still do the same authorization flow you are describing here, but it would be for any incoming HTTP request on localhost (possibly further restricted to require an auth token read from a file from the same directory as lbry-desktop - this way no foreign accounts/hosts could use it.)

I agree you want it to be two phase:

btzr-io commented 5 years ago

@EnigmaCurry This issue is to discuss embedded apps, but I like the idea of an extended api for external apps.

no ability to fullscreen

There is already a fullscreen feature implemented for the viewer implemented ( shortcut key + action button), but we could also launch it on an external window to give it more space freedom (see https://github.com/lbryio/lbry-desktop/issues/2516)

Instead of using window.LBRY_BRIDGE, which would limit access to only electron, I am wondering if an REST API listening on a port would be more flexible.

The lbry-sdk already has an api for this, external apps can talk directly with the daemon

HTTP request on localhost

This is not possible for security reasons on embedded apps.

possibly further restricted to require an auth token read from a file from the same directory as lbry-desktop - this way no foreign accounts/hosts could use it

This should probably be implemented on the lbry-sdk side and not in the app.

btzr-io commented 5 years ago

@EnigmaCurry I think embedded apps should be easy and fast to develop without the need to install any stuff or use complicated workflows, as simple as writing an html webpage. Hopefully this will increase the interest on the dev community to start adopting the usage of protocol.

If you need to build something more serious or complex projects then you can always create an external app and use whatever tools you like.

EnigmaCurry commented 5 years ago

fair enough. I was envisioning a centralized GUI inside the desktop app for authorizing this stuff rather than using lbrynet directly, so that is is as easy as possible for users to trust sending money. This way the user can do authorizations and such in one app. I realize this is a larger scope than what you are suggesting here, but it might impact the design if you think its a good idea to open it up to external apps.

EnigmaCurry commented 5 years ago

The LBRY_BRIDGE can do do the http request I imagine on the nodejs side, so the embedded app would just speak the same language as the REST api, but would do it through the bridge.

btzr-io commented 5 years ago

@EnigmaCurry Yes, that's how it should work :+1:

btzr-io commented 5 years ago

A more deep analysis of electron security and the preload implementation: https://doyensec.com/resources/Asia-19-Carettoni-Preloading-Insecurity-In-Your-Electron.pdf