GoogleChromeLabs / browser-fs-access

File System Access API with legacy fallback in the browser
https://googlechromelabs.github.io/browser-fs-access/demo/
Apache License 2.0
1.38k stars 84 forks source link

Add check if app is running in third- or first-party environment #38

Closed apnerve closed 3 years ago

apnerve commented 3 years ago

Tried embedding excalidraw inside an frame and file loading and saving started throwing an error in Chrome but works on firefox.

Failed to execute 'showOpenFilePicker' on 'Window': Cross origin sub frames aren't allowed to show a file picker.

On further inspection, it looks like the underlying error is because of using showOpenFilePicker being used by this library.

Tried to repro on codesandbox here - https://codesandbox.io/s/exciting-hertz-jzjeg?file=/src/index.js (works on firefox but not on chrome)

tomayac commented 3 years ago

You’re hitting a privacy limitation of the File System Access API (which is being used in this library): https://wicg.github.io/file-system-access/#privacy-third-party. This is working as intended. It works on Firefox because this browser doesn’t support that API, so uses the fallback route.

apnerve commented 3 years ago

Yes, I agree that it is as intended but it breaks the applications that use the library in certain use cases. It would be great if there is a way to let users choose whether they want the latest implementation or the fallback? That way applications dependant on this library can still work when embedded as an iframe. WDYT?

tomayac commented 3 years ago

The proper answer is to integrate with the Permissions Policy, as tracked in https://github.com/WICG/file-system-access/issues/245. As an intermediate workaround, this library could detect if it’s running in a third-party environment. I’ll check what I can do about this.

tomayac commented 3 years ago

Fixed with https://github.com/GoogleChromeLabs/browser-fs-access/commit/60b5dc149943fa04eae5c97d71a16f2c9bae8fae.

Pet3ris commented 3 years ago

Hi @apnerve, @tomayac - I tried the above Code Sandbox and it doesn't work on Chrome or Firefox (I suspect a file popup should open up to prompt me to choose a file from a local directory).

Are there any specific permissions that need to be granted at the browser level for this to work or am I misinterpreting what the outcome of the above async call should be?

tomayac commented 3 years ago

The Code Sandbox uses the old version of the library. Try this demo. Even on Chrome, a browser that supports the File System Access API, it needs to fall back to the legacy approach since the embedded content is cross-origin.

Pet3ris commented 3 years ago

Thanks - that works. I tried to update CodeSandbox library to 0.16.0 but it still doesn't work for me. Is there any particular trick to get it to work in CodeSandbox?

The cross-origin legacy downgrade makes sense!

tomayac commented 3 years ago

Hmm, I literally just updated the version number in the Code Sandbox demo and it started to pop the file open dialog open:

"browser-fs-access": "^0.16.0"
Pet3ris commented 3 years ago

I tried on Brave and Safari as well without luck.

However, if I do "open in a new window" with the CodeSandbox on chrome, it does give me a similar error:

Failed to execute 'showOpenFilePicker' on 'Window': Must be handling a user gesture to show a file picker.

On Firefox, the two errors are:

The user aborted a request.

keyEventHandler is not defined
tomayac commented 3 years ago

I tried on Brave and Safari as well without luck.

Screen Shot 2021-03-29 at 12 31 54

However, if I do "open in a new window" with the CodeSandbox on chrome, it does give me a similar error:

Failed to execute 'showOpenFilePicker' on 'Window': Must be handling a user gesture to show a file picker.

Yes, the file open dialog needs to be triggered by a user gesture; for example, a button press.

On Firefox, the two errors are:

The user aborted a request.
keyEventHandler is not defined

This happens when the user cancels the dialog.

Pet3ris commented 3 years ago

Yeah the Excalidraw example works well across all browsers for me, very weird that the CodeBrowser example doesn't work at all. I tried to click on the window as instructed but that just serves to trigger the respective errors unfortunately.

I'm planning to use the library for an app so wanted to just have a minimal reproducible example of how to use it and what the return values look like, may have to just start building the functionality directly.

tomayac commented 3 years ago

What's wrong with the official demo?

apnerve commented 3 years ago

Yeah the Excalidraw example works well across all browsers for me, very weird that the CodeBrowser example doesn't work at all. I tried to click on the window as instructed but that just serves to trigger the respective errors unfortunately.

I'm planning to use the library for an app so wanted to just have a minimal reproducible example of how to use it and what the return values look like, may have to just start building the functionality directly.

In case you meant the example I added in the issue, it doesn't take into account the click and hence doesn't work. Have bumped the version to ^0.16.0 and added a click handler and it works fine

Pet3ris commented 3 years ago

Thanks @apnerve, was able to reproduce and now integrated directories/files fully in the app :).

@tomayac nothing wrong with it whatsoever, just when I see a simple example not working in CodeSandbox that's usually a good prompt to improve my understanding of a dependency, so I start there first.

Thanks both for your help!