All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
160 lines
4.0 KiB
JavaScript
160 lines
4.0 KiB
JavaScript
import { app, ipcMain, shell, globalShortcut, safeStorage } from 'electron'
|
|
import Store from 'electron-store'
|
|
import { Buffer } from 'buffer'
|
|
import process from 'process'
|
|
import {
|
|
registerGlobalShortcuts,
|
|
setupSpotlightIPC
|
|
} from './spotlightWindow.js'
|
|
import {
|
|
createWindow,
|
|
setupMainWindowIPC,
|
|
setupMainWindowAppEvents,
|
|
setupDevAuthServer,
|
|
setupSingleInstanceLock,
|
|
handleDeepLinkFromArgv
|
|
} from './mainWindow.js'
|
|
import { setupAppUpdateIPC } from './appupdate.js'
|
|
|
|
// --- Auth session storage (main process) ---
|
|
const authStore = new Store({
|
|
name: 'auth-session'
|
|
})
|
|
const AUTH_SESSION_KEY = 'authSession'
|
|
const appSettingsStore = new Store({
|
|
name: 'settings'
|
|
})
|
|
const APP_SETTINGS_KEY = 'appSettings'
|
|
|
|
const serializeAuthSession = (session) => {
|
|
const sessionJson = JSON.stringify(session)
|
|
|
|
if (safeStorage.isEncryptionAvailable()) {
|
|
const encrypted = safeStorage.encryptString(sessionJson).toString('base64')
|
|
return {
|
|
encrypted: true,
|
|
value: encrypted
|
|
}
|
|
}
|
|
|
|
return {
|
|
encrypted: false,
|
|
value: sessionJson
|
|
}
|
|
}
|
|
|
|
const deserializeAuthSession = (storedValue) => {
|
|
if (!storedValue) return null
|
|
|
|
if (typeof storedValue === 'object' && storedValue.encrypted === true) {
|
|
if (!safeStorage.isEncryptionAvailable()) {
|
|
console.warn(
|
|
'[auth-session] Encrypted auth session exists but encryption is unavailable on this system.'
|
|
)
|
|
return null
|
|
}
|
|
const decrypted = safeStorage.decryptString(
|
|
Buffer.from(storedValue.value, 'base64')
|
|
)
|
|
return JSON.parse(decrypted)
|
|
}
|
|
|
|
if (typeof storedValue === 'object' && typeof storedValue.value === 'string') {
|
|
return JSON.parse(storedValue.value)
|
|
}
|
|
|
|
if (typeof storedValue === 'string') {
|
|
return JSON.parse(storedValue)
|
|
}
|
|
|
|
// Legacy safety net if the object shape already matches the session structure.
|
|
if (typeof storedValue === 'object' && storedValue.token) {
|
|
return storedValue
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
const gotTheLock = setupSingleInstanceLock(app)
|
|
|
|
if (gotTheLock) {
|
|
app.whenReady().then(() => {
|
|
createWindow()
|
|
registerGlobalShortcuts()
|
|
setupSpotlightIPC()
|
|
setupMainWindowIPC()
|
|
setupAppUpdateIPC(app)
|
|
setupMainWindowAppEvents(app)
|
|
setupDevAuthServer()
|
|
handleDeepLinkFromArgv()
|
|
})
|
|
}
|
|
|
|
app.on('will-quit', () => {
|
|
globalShortcut.unregisterAll()
|
|
})
|
|
|
|
// IPC handler to get OS
|
|
ipcMain.handle('os-info', () => {
|
|
return {
|
|
platform: process.platform
|
|
}
|
|
})
|
|
|
|
ipcMain.handle('auth-session-get', async () => {
|
|
try {
|
|
const storedValue = authStore.get(AUTH_SESSION_KEY)
|
|
return deserializeAuthSession(storedValue)
|
|
} catch (e) {
|
|
console.warn('[auth-session] Failed to read auth session.', e?.message || e)
|
|
return null
|
|
}
|
|
})
|
|
|
|
ipcMain.handle('auth-session-set', async (event, session) => {
|
|
try {
|
|
if (!session || typeof session !== 'object') return false
|
|
authStore.set(AUTH_SESSION_KEY, serializeAuthSession(session))
|
|
return true
|
|
} catch (e) {
|
|
console.warn('[auth-session] Failed to write auth session.', e?.message || e)
|
|
return false
|
|
}
|
|
})
|
|
|
|
ipcMain.handle('auth-session-clear', async () => {
|
|
try {
|
|
authStore.delete(AUTH_SESSION_KEY)
|
|
return true
|
|
} catch (e) {
|
|
console.warn('[auth-session] Failed to clear auth session.', e?.message || e)
|
|
return false
|
|
}
|
|
})
|
|
|
|
ipcMain.handle('app-settings-get', async () => {
|
|
try {
|
|
const settings = appSettingsStore.get(APP_SETTINGS_KEY)
|
|
return settings && typeof settings === 'object' ? settings : {}
|
|
} catch (e) {
|
|
console.warn('[app-settings] Failed to read settings.', e?.message || e)
|
|
return {}
|
|
}
|
|
})
|
|
|
|
ipcMain.handle('app-settings-set', async (event, settings) => {
|
|
try {
|
|
if (!settings || typeof settings !== 'object') return false
|
|
appSettingsStore.set(APP_SETTINGS_KEY, settings)
|
|
return true
|
|
} catch (e) {
|
|
console.warn('[app-settings] Failed to write settings.', e?.message || e)
|
|
return false
|
|
}
|
|
})
|
|
|
|
// IPC handler for opening external URLs
|
|
ipcMain.handle('open-external-url', (event, url) => {
|
|
shell.openExternal(url)
|
|
})
|