v1.8.0 #429

Merged
LukeGus merged 198 commits from dev-1.8.0 into main 2025-11-05 16:36:16 +00:00
11 changed files with 128 additions and 26 deletions
Showing only changes of commit a52a5217bf - Show all commits

View File

@@ -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 });

View File

@@ -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"],

View File

@@ -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,

View File

@@ -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"],

View File

@@ -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"],

View File

@@ -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"],

View File

@@ -76,25 +76,23 @@ function RootApp() {
return (
<>
{isElectron() && (
<div
className="fixed inset-0 pointer-events-none"
style={{
backgroundColor: "#09090b",
backgroundImage: `linear-gradient(
135deg,
transparent 0%,
transparent 49%,
rgba(255, 255, 255, 0.03) 49%,
rgba(255, 255, 255, 0.03) 51%,
transparent 51%,
transparent 100%
)`,
backgroundSize: "80px 80px",
zIndex: 0,
}}
/>
)}
<div
className="fixed inset-0 pointer-events-none"
style={{
backgroundColor: "#09090b",
backgroundImage: `linear-gradient(
135deg,
transparent 0%,
transparent 49%,
rgba(255, 255, 255, 0.03) 49%,
rgba(255, 255, 255, 0.03) 51%,
transparent 51%,
transparent 100%
)`,
backgroundSize: "80px 80px",
zIndex: 0,
}}
/>
<div className="relative min-h-screen" style={{ zIndex: 1 }}>
{isElectron() && showVersionCheck ? (
<ElectronVersionCheck

View File

@@ -646,7 +646,21 @@ export function Auth({
);
}
if (isElectron() && currentServerUrl && !loggedIn && !authLoading) {
if (isElectron() && currentServerUrl && authLoading) {
return (
<div
className={`w-[420px] max-w-full p-6 flex flex-col bg-dark-bg border-2 border-dark-border rounded-md overflow-y-auto my-2 ${className || ""}`}
style={{ maxHeight: "calc(100vh - 1rem)" }}
{...props}
>
<div className="flex items-center justify-center h-32">
<div className="w-6 h-6 border-2 border-primary border-t-transparent rounded-full animate-spin" />
</div>
</div>
);
}
if (isElectron() && currentServerUrl && !loggedIn) {
return (
<div
className="w-full h-screen flex items-center justify-center p-4"

View File

@@ -129,6 +129,36 @@ export function ElectronLoginForm({
}
}
function clearAuthData() {
try {
localStorage.removeItem('jwt');
sessionStorage.removeItem('jwt');
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i];
const eqPos = cookie.indexOf('=');
const name = eqPos > -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}
/>
</div>
</div>

View File

@@ -395,7 +395,7 @@ export function LeftSidebar({
>
<span>{t("profile.title")}</span>
</DropdownMenuItem>
{isAdmin && !isElectron() && (
{isAdmin && (
<DropdownMenuItem
className="rounded px-2 py-1.5 hover:bg-white/15 hover:text-accent-foreground focus:bg-white/20 focus:text-accent-foreground cursor-pointer focus:outline-none"
onClick={() => {

View File

@@ -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();