Ask the user for cookies access when running in iframe in Safari (#1862)

This commit is contained in:
Jonatan Kłosko 2023-04-13 20:39:25 +02:00 committed by GitHub
parent 6ebcdf20b4
commit 8e02e0154d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -18,6 +18,7 @@ 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";
function connect() {
const csrfToken = document const csrfToken = document
.querySelector("meta[name='csrf-token']") .querySelector("meta[name='csrf-token']")
.getAttribute("content"); .getAttribute("content");
@ -58,3 +59,56 @@ liveSocket.connect();
// >> 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();
}