diff --git a/.github/workflows/electron.yml b/.github/workflows/electron.yml index 8b785c18..2c37767c 100644 --- a/.github/workflows/electron.yml +++ b/.github/workflows/electron.yml @@ -409,11 +409,10 @@ jobs: APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} run: | - if [ "${{ steps.check_certs.outputs.has_certs }}" == "true" ]; then - npx electron-builder --mac dmg --universal --x64 --arm64 --publish never - else - npm run build && npx electron-builder --mac dmg --universal --x64 --arm64 --publish never + if [ "${{ steps.check_certs.outputs.has_certs }}" != "true" ]; then + npm run build fi + npx electron-builder --mac dmg --universal --x64 --arm64 --publish never - name: List release directory if: steps.check_certs.outputs.has_certs == 'true' diff --git a/electron/main.cjs b/electron/main.cjs index 0d3a2c6e..accffe28 100644 --- a/electron/main.cjs +++ b/electron/main.cjs @@ -41,6 +41,10 @@ if (!gotTheLock) { } function createWindow() { + const appVersion = app.getVersion(); + const electronVersion = process.versions.electron; + const platform = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux"; + mainWindow = new BrowserWindow({ width: 1200, height: 800, @@ -63,6 +67,10 @@ function createWindow() { mainWindow.setMenuBarVisibility(false); } + mainWindow.webContents.setUserAgent( + `Termix-Desktop/${appVersion} (${platform}; Electron/${electronVersion})` + ); + if (isDev) { mainWindow.loadURL("http:://localhost:5173"); mainWindow.webContents.openDevTools(); diff --git a/package.json b/package.json index 54b012e7..bd71b467 100644 --- a/package.json +++ b/package.json @@ -18,16 +18,13 @@ "build:backend": "tsc -p tsconfig.node.json", "dev:backend": "tsc -p tsconfig.node.json && node ./dist/backend/backend/starter.js", "preview": "vite preview", - "electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:5173 && electron .\"", + "electron:dev": "concurrently \"npm run dev\" \"powershell -c \\\"Start-Sleep -Seconds 5\\\" && electron .\"", "build:win-portable": "npm run build && electron-builder --win --dir", "build:win-installer": "npm run build && electron-builder --win --publish=never", "build:linux-portable": "npm run build && electron-builder --linux --dir", "build:linux-appimage": "npm run build && electron-builder --linux AppImage", "build:linux-targz": "npm run build && electron-builder --linux tar.gz", - "build:mac": "npm run build && electron-builder --mac --universal", - "test:encryption": "tsc -p tsconfig.node.json && node ./dist/backend/backend/utils/encryption-test.js", - "migrate:encryption": "tsc -p tsconfig.node.json && node ./dist/backend/backend/utils/encryption-migration.js", - "prepare": "husky" + "build:mac": "npm run build && electron-builder --mac --universal" }, "dependencies": { "@codemirror/autocomplete": "^6.18.7", diff --git a/src/backend/utils/auth-manager.ts b/src/backend/utils/auth-manager.ts index ead14851..e1aa0cd1 100644 --- a/src/backend/utils/auth-manager.ts +++ b/src/backend/utils/auth-manager.ts @@ -267,15 +267,6 @@ class AuthManager { .limit(1); if (sessionRecords.length === 0) { - databaseLogger.warn( - "JWT token has no matching session in database", - { - operation: "jwt_verify_failed", - reason: "session_not_found", - sessionId: payload.sessionId, - userId: payload.userId, - }, - ); return null; } } catch (dbError) { diff --git a/src/backend/utils/user-agent-parser.ts b/src/backend/utils/user-agent-parser.ts index d8d1bd6d..74e0dca7 100644 --- a/src/backend/utils/user-agent-parser.ts +++ b/src/backend/utils/user-agent-parser.ts @@ -14,7 +14,7 @@ export function detectPlatform(req: Request): DeviceType { const userAgent = req.headers["user-agent"] || ""; const electronHeader = req.headers["x-electron-app"]; - if (electronHeader === "true") { + if (electronHeader === "true" || userAgent.includes("Termix-Desktop")) { return "desktop"; } @@ -44,22 +44,30 @@ function parseElectronUserAgent(userAgent: string): DeviceInfo { let os = "Unknown OS"; let version = "Unknown"; - if (userAgent.includes("Windows")) { - os = parseWindowsVersion(userAgent); - } else if (userAgent.includes("Mac OS X")) { - os = parseMacVersion(userAgent); - } else if (userAgent.includes("Linux")) { - os = "Linux"; - } + const termixMatch = userAgent.match(/Termix-Desktop\/([\d.]+) \(([^;]+);/); + if (termixMatch) { + version = termixMatch[1]; + os = termixMatch[2]; + } else { + if (userAgent.includes("Windows")) { + os = parseWindowsVersion(userAgent); + } else if (userAgent.includes("Mac OS X")) { + os = parseMacVersion(userAgent); + } else if (userAgent.includes("macOS")) { + os = "macOS"; + } else if (userAgent.includes("Linux")) { + os = "Linux"; + } - const electronMatch = userAgent.match(/Electron\/([\d.]+)/); - if (electronMatch) { - version = electronMatch[1]; + const electronMatch = userAgent.match(/Electron\/([\d.]+)/); + if (electronMatch) { + version = electronMatch[1]; + } } return { type: "desktop", - browser: "Electron", + browser: "Termix Desktop", version, os, deviceInfo: `Termix Desktop on ${os}`, diff --git a/src/ui/desktop/authentication/ElectronLoginForm.tsx b/src/ui/desktop/authentication/ElectronLoginForm.tsx index 74abc553..c64fdde7 100644 --- a/src/ui/desktop/authentication/ElectronLoginForm.tsx +++ b/src/ui/desktop/authentication/ElectronLoginForm.tsx @@ -23,6 +23,7 @@ export function ElectronLoginForm({ const iframeRef = useRef(null); const hasAuthenticatedRef = useRef(false); const [currentUrl, setCurrentUrl] = useState(serverUrl); + const hasLoadedOnce = useRef(false); useEffect(() => { const handleMessage = async (event: MessageEvent) => { @@ -52,7 +53,7 @@ export function ElectronLoginForm({ throw new Error("Failed to save JWT to localStorage"); } - await new Promise((resolve) => setTimeout(resolve, 200)); + await new Promise((resolve) => setTimeout(resolve, 500)); onAuthSuccess(); } catch (err) { @@ -81,6 +82,8 @@ export function ElectronLoginForm({ const handleLoad = () => { setLoading(false); + hasLoadedOnce.current = true; + setError(null); try { if (iframe.contentWindow) { @@ -200,7 +203,9 @@ export function ElectronLoginForm({ const handleError = () => { setLoading(false); - setError(t("errors.failedToLoadServer")); + if (hasLoadedOnce.current) { + setError(t("errors.failedToLoadServer")); + } }; iframe.addEventListener("load", handleLoad);