-
Notifications
You must be signed in to change notification settings - Fork 14
First draft of dat RPC implementation #5
base: master
Are you sure you want to change the base?
Conversation
After some researching it appears that lack of |
@Gozala That's how I figured this would be solved. I haven't dug in yet to see if we can get exactly what we want, but I'd start there. |
I did bunch of fixes. All WRITE APIs except |
I should note that RPC API only works with |
Submitted following issues to an electron electron/electron#14720 electron/electron#14746 electron/electron#14747 |
After some more digging on pointers from electron/electron#7931 it appears to me that I was also able to verify that whenever request is coming from different origin In fact such request causes a preflight OPTIONS request to the protocol handler and only lets actual request to go through if response to it allows requested method, origin, headers (here is the illustration https://github.com/Gozala/electron-quick-start/blob/origin-header/protocol.js#L33-L44) What is unclear to me - I don't believe beaker handles such requests (I have not seen evidence of it at least) but somehow cross-origin request still seem to succeed. Which makes me wonder if there is a difference in scheme configuration here is one used in the example I am also uncertain what would happen if source beaker-core/web-apis/bg/dat-archive.js Lines 595 to 600 in 76d0074
That I don't actually know what it does but I suspect it requires |
I guess |
As of API needs to figure out what window does sender corresponds to in order to I presume do user prompt. Which does also raises a more general question unrelated to this Assuming we eventually have DatArchive API in ServiceWorker / Worker / (hidden) iframe where would that user prompt be displayed in that case ? @pfrazee I presume answer to that question would also dictate solution for this specific limitation. |
That's a really tough call. Iframes could mislead the user if they prompt within the parent frame, and service workers may be running without a frame active (I believe). |
Yes. In fact fetch to a url handled by registered service worker should activate it unless it already is active |
After seating on this for a day I think there are two options:
|
One more thought - If app is talking to other app in iframe or a service worker which is asking for permission it might be reasonable to display permission prompt ancored to a visible tab that is initiating request flow (it would be still nice to clarify via icon / url the site permission is being granred to). In worst case user may mistake that for a request from initiating page, but that’s in a way not a mistake, that page is requesting mediated permission. Also in worst case scenario BAD app may get access to some dat but on the other can app considered to be GOOD if it’s doing exchange with BAD one ? I’m inclined to say no. |
I propose to extend DatArchive API as follows: Add optional
That would allow one app to request access on another apps behalf. Which IMO would provide reasonable way for collaborative apps to request desired permission. For example - app A is interacting with app B’s service worker, which needs to create / select / fork an archive. B can respond to A asking it to request corresponding permission on it’s behalf. App A then could call corresponding DatArchive API method with With this in place it would be fairly reasonable to allow permission prompts only from the top level documents. And most interactions could provide reasonable UX (as long as prompts reflect designated owner) Only unfortunate consequence is that app performing request on others behalf will learn the URL of the dat that user granted permission for which may be undesired. |
I have misunderstood This means that my proposal as described in previous comment (which I started implementing) is not going to work. Because even if provider app (hidden iframe / worker / service worker) app may ask user to select archive through a consumer app (displayed by an active tab) mediation, provider will still fail to write as there will be no place to display user prompt. Only solution I can think of right now is to extend one more method P.S.: I do like that provider and consumer apps need to cooperate in order to request access from a user. IMO it is much better than say allow provider to request access on it's own, because cooperation makes it impossible for provider to trick user into thinking that consumer requested permission, instead it needs a to convince consumer to actually do that on it's behalf. |
Hey @pfrazee any feedback on the proposed "mediated permissions" solution ? And more generally this pull request ? Implementation already started to rot, so I'd like to have some closure which is either:
I would argue that even with the following limitations:
This changes provide enough value to justify them. It would allow use of dat archive APIs in both iframes and workers. And lack of permission requests could be overcome by opening top level window to request them if necessary. |
Overview of changes
dat/protocol.js
. (I did not wanted to, but I'm afraid I was unable to following the logic, I hope it's ok). I made logic more linear so it's easier to make sense of it.normalizeFilepath
fromweb-apis/bg/dat-archive.js
so I factored it out todat/util.js
& import from both modules.timer
function used all acrossweb-apis/bg/dat-archive.js
was serving the same purpose, so I end up importing and using it intodat/protocol.js
as well.match
takes request and returns a corresponding handler which makes it a lot easier IMO to figure what route is taken. Former handler ended up being split into twoserveEntry
anddownloadZip
handlers. All the other handlers are matched according to REST interface spec.dat/rpc.js
module and are pretty much wrappers for corresponding functions indat/protocol.js
which just take care of translating query arguments, uploadData and URL to corresponding arguments & then translating results back toStreamProtocolResponse
objects.Status
I did some manual testing yesterday and fixed bunch of bugs (forgot to push them, but did that just now). From what I can tell all the READ functionality works as expected.For whatever reasonwatch
API does not work and I'll have to look more into it.All the WRITE functionality is broken. Idea was to letweb-apis/bg/dat-archive.js
do it's normal access control checks usingreferrer
of the request, but it seems that electron does not bother to set it anything other than''
nor I managed to get it to sendOrigin
header.Open questions
watch
API is tricky in that how does one unsubscribe ? I don't seems to see how one could detect that connection was dropped.As mentioned in above section figuring out how to communicate where request originated from is crucial to making WRITE APIs work.Turns out "null" origin is set for request from same origin and actual Origin is included for requests from other origins.createArchive
\selectArchive
APIs available indat/rpc.js
module, which are not exposed. I think we need to discuss exposing them as well, because without them WRITE APIs are not going to be all that useful. On the other hand though it brings up UX question - how does beaker communicate which app is requesting write permission.I think this has potential to unlock