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

Allow "Render with Voilà" button to open new tab #1507

Open
minrk opened this issue Oct 29, 2024 · 3 comments
Open

Allow "Render with Voilà" button to open new tab #1507

minrk opened this issue Oct 29, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@minrk
Copy link
Contributor

minrk commented Oct 29, 2024

Problem

JupyterHub CORS policy usually prohibits embedding Jupyter Server pages in iframes, which means the in-panel voila viewer in the JupyterLab extension doesn't work:

Refused to load https://jupyterhub.example.org/user/minrk/voila/render//sample-charts.ipynb because it does not appear in the frame-ancestors directive of the Content Security Policy.

But launching in a new tab works fine:

Screenshot 2024-10-29 at 11 24 43

Aside: it would probably be appropriate to display an error if you can detect it, rather than purely an empty white panel with no messages visible to the user except in the js console.

Proposed Solution

It would be nice to have a configuration option to set the voilà toolbar button to invoke the "Open with Voila in new browser tab" action instead of the preview pane when it doesn't work.

Double nice, though I'm not sure it is possible, would be launch the tab automatically if the IFrame fails to load. I'm not sure that is doable, though, and I assume pop up blockers would prevent it since it would be too far removed from the click event.

Additional context

JupyterHub default CORS does not allow frame-ancestors: self because multiple users share the same domain in the default configuration, so no iframe is safe.

@minrk minrk added the enhancement New feature or request label Oct 29, 2024
@cosmicfarmers
Copy link

cosmicfarmers commented Dec 4, 2024

Hello,

I have the same (maybe) issue.

I tried the below but it is ignored; the frame-ancestors is still none.
https://discourse.jupyter.org/t/button-render-with-voila-connection-refused/26435/4

Error:
Refused to frame '<my_host>' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'none'".

Have you tried the solution in the link?

@minrk
Copy link
Contributor Author

minrk commented Dec 4, 2024

The solution in the link doesn't work for me because that's explicitly disabling security protections for the Jupyter server, granting all users of the Hub full access to each others' servers. I would like to be able to use the button without disabling security.

@minrk
Copy link
Contributor Author

minrk commented Dec 20, 2024

I did find a way that appears to work to keep voilà iframes working: get the page content with fetch, then load it with srcdoc instead of src:

// fetch HTML with credentials
r = await fetch(url, {headers: Authorization: "Bearer TOKEN"})
html = await r.text()
// put HTML in iframe srcdoc to avoid CSP issues on src
iframe.srcdoc = html

This works because fetch can use proper credentials to verify that it's originating from an authenticated source, which iframe src= can't do in jupyterhub (I believe it's impossible to distinguish requests from /user/you from /user/me other than using access tokens or csrf tokens). It also works for voila because they are single pages. It won't work for other iframes that have in-page navigation, because the URL is lost and the navigation requests will subsequently be blocked by frame-ancestors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants