diff --git a/electron/main.cjs b/electron/main.cjs index 2b0765e6..58c0f5b9 100644 --- a/electron/main.cjs +++ b/electron/main.cjs @@ -64,6 +64,8 @@ function createWindow() { contextIsolation: true, webSecurity: true, preload: path.join(__dirname, "preload.js"), + partition: "persist:termix", + allowRunningInsecureContent: false, }, show: false, }); @@ -123,6 +125,20 @@ function createWindow() { delete headers["Content-Security-Policy"]; } } + + if (headers["set-cookie"]) { + headers["set-cookie"] = headers["set-cookie"].map((cookie) => { + let modified = cookie.replace(/;\s*SameSite=Strict/gi, "; SameSite=None"); + modified = modified.replace(/;\s*SameSite=Lax/gi, "; SameSite=None"); + if (!modified.includes("SameSite=")) { + modified += "; SameSite=None"; + } + if (!modified.includes("Secure") && details.url.startsWith("https")) { + modified += "; Secure"; + } + return modified; + }); + } } callback({ responseHeaders: headers }); diff --git a/src/backend/dashboard.ts b/src/backend/dashboard.ts index 8298045f..465ab9d8 100644 --- a/src/backend/dashboard.ts +++ b/src/backend/dashboard.ts @@ -37,7 +37,11 @@ app.use( return callback(null, true); } - callback(null, true); + if (origin.startsWith("http://")) { + return callback(null, true); + } + + callback(new Error("Not allowed by CORS")); }, credentials: true, methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], diff --git a/src/backend/database/database.ts b/src/backend/database/database.ts index 38bee98d..661549b5 100644 --- a/src/backend/database/database.ts +++ b/src/backend/database/database.ts @@ -68,6 +68,10 @@ app.use( return callback(null, true); } + if (origin.startsWith("http://")) { + return callback(null, true); + } + callback(new Error("Not allowed by CORS")); }, credentials: true, diff --git a/src/backend/ssh/file-manager.ts b/src/backend/ssh/file-manager.ts index c8a8bbd0..b1e0cdba 100644 --- a/src/backend/ssh/file-manager.ts +++ b/src/backend/ssh/file-manager.ts @@ -65,7 +65,11 @@ app.use( return callback(null, true); } - callback(null, true); + if (origin.startsWith("http://")) { + return callback(null, true); + } + + callback(new Error("Not allowed by CORS")); }, credentials: true, methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], diff --git a/src/backend/ssh/server-stats.ts b/src/backend/ssh/server-stats.ts index 6325da45..152e941d 100644 --- a/src/backend/ssh/server-stats.ts +++ b/src/backend/ssh/server-stats.ts @@ -603,7 +603,11 @@ app.use( return callback(null, true); } - callback(null, true); + if (origin.startsWith("http://")) { + return callback(null, true); + } + + callback(new Error("Not allowed by CORS")); }, credentials: true, methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], diff --git a/src/backend/ssh/tunnel.ts b/src/backend/ssh/tunnel.ts index 8790392e..3dff10eb 100644 --- a/src/backend/ssh/tunnel.ts +++ b/src/backend/ssh/tunnel.ts @@ -41,7 +41,11 @@ app.use( return callback(null, true); } - callback(null, true); + if (origin.startsWith("http://")) { + return callback(null, true); + } + + callback(new Error("Not allowed by CORS")); }, credentials: true, methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], diff --git a/src/main.tsx b/src/main.tsx index 31612fdf..53ff210e 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -76,25 +76,23 @@ function RootApp() { return ( <> - {isElectron() && ( -
- )} +
{isElectron() && showVersionCheck ? ( +
+
+
+
+ ); + } + + if (isElectron() && currentServerUrl && !loggedIn) { return (
-1 ? cookie.substr(0, eqPos).trim() : cookie.trim(); + if (name === 'jwt') { + document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/'; + document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/;domain=' + window.location.hostname; + } + } + } catch (error) { + } + } + + window.addEventListener('message', function(event) { + try { + if (event.data && typeof event.data === 'object') { + if (event.data.type === 'CLEAR_AUTH_DATA') { + clearAuthData(); + } + } + } catch (error) { + } + }); + function checkAuth() { try { const localToken = localStorage.getItem('jwt'); @@ -312,7 +342,8 @@ export function ElectronLoginForm({ className="w-full h-full border-0" title="Server Authentication" sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-storage-access-by-user-activation allow-top-navigation allow-top-navigation-by-user-activation allow-modals allow-downloads" - allow="clipboard-read; clipboard-write; cross-origin-isolated; camera; microphone; geolocation" + allow="clipboard-read; clipboard-write; cross-origin-isolated; camera; microphone; geolocation; storage-access" + credentialless={false} />
diff --git a/src/ui/desktop/navigation/LeftSidebar.tsx b/src/ui/desktop/navigation/LeftSidebar.tsx index d432ae72..0021283e 100644 --- a/src/ui/desktop/navigation/LeftSidebar.tsx +++ b/src/ui/desktop/navigation/LeftSidebar.tsx @@ -395,7 +395,7 @@ export function LeftSidebar({ > {t("profile.title")} - {isAdmin && !isElectron() && ( + {isAdmin && ( { diff --git a/src/ui/desktop/user/UserProfile.tsx b/src/ui/desktop/user/UserProfile.tsx index 8aa937cf..3f53d511 100644 --- a/src/ui/desktop/user/UserProfile.tsx +++ b/src/ui/desktop/user/UserProfile.tsx @@ -34,6 +34,29 @@ async function handleLogout() { if (isElectron()) { localStorage.removeItem("jwt"); + + const configuredServerUrl = ( + window as Window & + typeof globalThis & { + configuredServerUrl?: string; + } + ).configuredServerUrl; + + if (configuredServerUrl) { + const iframe = document.querySelector("iframe"); + if (iframe && iframe.contentWindow) { + try { + const serverOrigin = new URL(configuredServerUrl).origin; + iframe.contentWindow.postMessage( + { + type: "CLEAR_AUTH_DATA", + timestamp: Date.now(), + }, + serverOrigin, + ); + } catch (err) {} + } + } } window.location.reload();