mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-02-22 13:53:23 +08:00
Ask the user for cookies access when running in iframe in Safari (#1862)
This commit is contained in:
parent
6ebcdf20b4
commit
8e02e0154d
1 changed files with 88 additions and 34 deletions
122
assets/js/app.js
122
assets/js/app.js
|
@ -18,43 +18,97 @@ import { loadAppAuthToken } from "./lib/app";
|
||||||
import { settingsStore } from "./lib/settings";
|
import { settingsStore } from "./lib/settings";
|
||||||
import { registerTopbar, registerGlobalEventHandlers } from "./events";
|
import { registerTopbar, registerGlobalEventHandlers } from "./events";
|
||||||
|
|
||||||
const csrfToken = document
|
function connect() {
|
||||||
.querySelector("meta[name='csrf-token']")
|
const csrfToken = document
|
||||||
.getAttribute("content");
|
.querySelector("meta[name='csrf-token']")
|
||||||
|
.getAttribute("content");
|
||||||
|
|
||||||
const liveSocket = new LiveSocket(
|
const liveSocket = new LiveSocket(
|
||||||
window.LIVEBOOK_BASE_URL_PATH + "/live",
|
window.LIVEBOOK_BASE_URL_PATH + "/live",
|
||||||
Socket,
|
Socket,
|
||||||
{
|
{
|
||||||
params: (liveViewName) => {
|
params: (liveViewName) => {
|
||||||
return {
|
return {
|
||||||
_csrf_token: csrfToken,
|
_csrf_token: csrfToken,
|
||||||
// Pass the most recent user data to the LiveView in `connect_params`
|
// Pass the most recent user data to the LiveView in `connect_params`
|
||||||
user_data: loadUserData(),
|
user_data: loadUserData(),
|
||||||
app_auth_token: loadAppAuthToken(),
|
app_auth_token: loadAppAuthToken(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
hooks: hooks,
|
hooks: hooks,
|
||||||
dom: morphdomOptions,
|
dom: morphdomOptions,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Show progress bar on live navigation and form submits
|
// Show progress bar on live navigation and form submits
|
||||||
registerTopbar();
|
registerTopbar();
|
||||||
|
|
||||||
// Handle custom events dispatched with JS.dispatch/3
|
// Handle custom events dispatched with JS.dispatch/3
|
||||||
registerGlobalEventHandlers();
|
registerGlobalEventHandlers();
|
||||||
|
|
||||||
// Reflect global configuration in attributes to enable CSS rules
|
// Reflect global configuration in attributes to enable CSS rules
|
||||||
settingsStore.getAndSubscribe((settings) => {
|
settingsStore.getAndSubscribe((settings) => {
|
||||||
document.body.setAttribute("data-editor-theme", settings.editor_theme);
|
document.body.setAttribute("data-editor-theme", settings.editor_theme);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Connect if there are any LiveViews on the page
|
// Connect if there are any LiveViews on the page
|
||||||
liveSocket.connect();
|
liveSocket.connect();
|
||||||
|
|
||||||
// Expose liveSocket on window for web console debug logs and latency simulation:
|
// Expose liveSocket on window for web console debug logs and latency simulation:
|
||||||
// >> liveSocket.enableDebug()
|
// >> liveSocket.enableDebug()
|
||||||
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
|
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
|
||||||
// >> liveSocket.disableLatencySim()
|
// >> liveSocket.disableLatencySim()
|
||||||
window.liveSocket = liveSocket;
|
window.liveSocket = liveSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When Livebook runs in a cross-origin iframe the browser may restrict access
|
||||||
|
// to cookies. This is the case in Safari with the "Prevent cross-site tracking"
|
||||||
|
// option enabled, which is the default. Without cookies access, the session
|
||||||
|
// is not stored, so CSRF tokens are invalid. Consequently, LV keeps reloading
|
||||||
|
// the page, as we try to connect the socket with invalid token. To work around
|
||||||
|
// this we need to ask to explicitly grant access to cookies, as outlined in (1).
|
||||||
|
//
|
||||||
|
// (1): https://developer.mozilla.org/en-US/docs/Web/API/Storage_Access_API
|
||||||
|
|
||||||
|
if (document.hasStorageAccess) {
|
||||||
|
document.hasStorageAccess().then((hasStorageAccess) => {
|
||||||
|
if (hasStorageAccess) {
|
||||||
|
connect();
|
||||||
|
} else {
|
||||||
|
const overlayEl = document.createElement("div");
|
||||||
|
|
||||||
|
overlayEl.innerHTML = `
|
||||||
|
<div class="fixed top-0 bottom-0 left-0 right-0 z-[1000] px-4 py-8 bg-gray-900/95 flex justify-center items-center">
|
||||||
|
<div class="max-w-[600px] w-full flex flex-col">
|
||||||
|
<div class="text-xl text-gray-100 font-medium">
|
||||||
|
Action required
|
||||||
|
</div>
|
||||||
|
<div class="mt-3 text-sm text-gray-300">
|
||||||
|
It looks like Livebook does not have access to cookies. This usually happens when
|
||||||
|
it runs in an iframe. To make the app functional you need to grant Livebook access
|
||||||
|
to its cookies explicitly.
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button id="grant-access" class="mt-6 button-base button-blue">
|
||||||
|
Grant access
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(overlayEl);
|
||||||
|
|
||||||
|
const grantAccessButtonEl = overlayEl.querySelector("#grant-access");
|
||||||
|
|
||||||
|
grantAccessButtonEl.addEventListener("click", (event) => {
|
||||||
|
document
|
||||||
|
.requestStorageAccess()
|
||||||
|
.then(() => window.location.reload())
|
||||||
|
.catch(() => console.log("Access to storage denied"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue