Add Electron main process with token management and navigation setup

- Implement main and login windows for Electron.
- Integrate `electron-store` for secure token storage and management.
- Setup IPC handlers for authentication.
- Update dependencies to support Electron, including `vite`, `react-router-dom`, and plugins.
This commit is contained in:
natreex
2025-11-16 13:55:08 -05:00
parent 1e6ebba56d
commit de03dedaf0
8 changed files with 1066 additions and 4 deletions

178
electron/main.ts Normal file
View File

@@ -0,0 +1,178 @@
import { app, BrowserWindow, ipcMain } from 'electron';
import * as path from 'path';
import * as url from 'url';
import { fileURLToPath } from 'url';
import Store from 'electron-store';
// Fix pour __dirname en ES modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const isDev = process.env.NODE_ENV === 'development';
// Définir le nom de l'application
app.setName('ERitors Scribe');
// En dev, __dirname pointe vers electron/, en prod vers dist/electron/
const preloadPath = isDev
? path.join(__dirname, '../dist/electron/preload.js')
: path.join(__dirname, 'preload.js');
// Icône de l'application
const iconPath = isDev
? path.join(__dirname, '../build/icon.png')
: path.join(__dirname, '../build/icon.png');
// Store sécurisé pour le token
const store = new Store({
encryptionKey: 'eritors-scribe-secure-key' // En production, utiliser une clé générée
});
let mainWindow: BrowserWindow | null = null;
let loginWindow: BrowserWindow | null = null;
function createLoginWindow(): void {
loginWindow = new BrowserWindow({
width: 500,
height: 900,
resizable: false,
icon: iconPath,
webPreferences: {
preload: preloadPath,
contextIsolation: true,
nodeIntegration: false,
sandbox: true,
},
frame: true,
show: false,
});
if (isDev) {
const devPort = process.env.PORT || '4000';
loginWindow.loadURL(`http://localhost:${devPort}/login/login`);
loginWindow.webContents.openDevTools();
} else {
loginWindow.loadURL(
url.format({
pathname: path.join(__dirname, '../out/login/login/index.html'),
protocol: 'file:',
slashes: true,
})
);
}
loginWindow.once('ready-to-show', () => {
loginWindow?.show();
});
loginWindow.on('closed', () => {
loginWindow = null;
});
}
function createMainWindow(): void {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
icon: iconPath,
webPreferences: {
preload: preloadPath,
contextIsolation: true,
nodeIntegration: false,
sandbox: true,
},
show: false,
});
if (isDev) {
const devPort = process.env.PORT || '4000';
mainWindow.loadURL(`http://localhost:${devPort}`);
mainWindow.webContents.openDevTools();
} else {
mainWindow.loadURL(
url.format({
pathname: path.join(__dirname, '../out/index.html'),
protocol: 'file:',
slashes: true,
})
);
}
mainWindow.once('ready-to-show', () => {
mainWindow?.show();
});
mainWindow.on('closed', () => {
mainWindow = null;
});
}
// IPC Handlers pour la gestion du token
ipcMain.handle('get-token', () => {
return store.get('authToken', null);
});
ipcMain.handle('set-token', (_event, token: string) => {
store.set('authToken', token);
return true;
});
ipcMain.handle('remove-token', () => {
store.delete('authToken');
return true;
});
ipcMain.on('login-success', (_event, token: string) => {
store.set('authToken', token);
if (loginWindow) {
loginWindow.close();
}
createMainWindow();
});
ipcMain.on('logout', () => {
store.delete('authToken');
if (mainWindow) {
mainWindow.close();
}
createLoginWindow();
});
app.whenReady().then(() => {
// Définir l'icône du Dock sur macOS
if (process.platform === 'darwin' && app.dock) {
app.dock.setIcon(iconPath);
}
// Vérifier si un token existe
const token = store.get('authToken');
if (token) {
// Token existe, ouvrir la fenêtre principale
createMainWindow();
} else {
// Pas de token, ouvrir la fenêtre de login
createLoginWindow();
}
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
const token = store.get('authToken');
if (token) {
createMainWindow();
} else {
createLoginWindow();
}
}
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});