131 lines
3.1 KiB
JavaScript
131 lines
3.1 KiB
JavaScript
import { app, ipcMain, shell, globalShortcut, safeStorage } from 'electron'
|
|
import Store from 'electron-store'
|
|
import {
|
|
registerGlobalShortcuts,
|
|
setupSpotlightIPC
|
|
} from './spotlightWindow.js'
|
|
import {
|
|
createWindow,
|
|
setupMainWindowIPC,
|
|
setupMainWindowAppEvents,
|
|
setupDevAuthServer,
|
|
setupSingleInstanceLock,
|
|
handleDeepLinkFromArgv
|
|
} from './mainWindow.js'
|
|
|
|
// --- Auth session storage (main process) ---
|
|
const authStore = new Store({
|
|
name: 'auth-session'
|
|
})
|
|
const AUTH_SESSION_KEY = 'authSession'
|
|
|
|
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()
|
|
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
|
|
}
|
|
})
|
|
|
|
// IPC handler for opening external URLs
|
|
ipcMain.handle('open-external-url', (event, url) => {
|
|
shell.openExternal(url)
|
|
})
|