refactor: Revise configuration and IPC architecture documentation for clarity and security enhancements

- Updated CONFIGURATION.md to reflect changes in target app orchestration, environment variables, and production routing.
- Enhanced IPC_ARCHITECTURE.md with a focus on privilege separation, standardized operating procedures, and critical audit checklists.
- Added detailed guidelines for extending the IPC bridge and maintaining security integrity.
- Introduced new package scripts for macOS, Windows, and Linux builds in package.json.
This commit is contained in:
Firman Ramdhani
2026-04-06 10:17:32 +07:00
parent 8cac18edf4
commit 75deeece9f
6 changed files with 773 additions and 367 deletions
+97 -45
View File
@@ -1,6 +1,8 @@
# Eigen Desktop
# Desktop
An Electron wrapper for the web applications in this monorepo. Powered by **electron-vite** for development and **electron-builder** for production packaging.
The native gateway for our monorepo applications.
> This package serves as a secure, high-performance Electron wrapper that transforms our web-based assets into first-class desktop experiences. Built on top of **electron-vite** for near-instant development cycles and **electron-builder** for seamless cross-platform distribution.
---
@@ -26,10 +28,10 @@ pnpm package:desktop
## How It Works
| Environment | Behavior |
| Environment | Operational Logic |
|---|---|
| **Development** | Electron loads the Vite dev server (`http://localhost:5173`). Hot reload works normally. |
| **Production** | Electron registers a custom `app://` protocol that serves the static build output of the target web app. SPA client-side routing is fully supported via an `index.html` fallback. |
| **Development** | Bridges the Electron shell with the Vite Dev Server, enabling Hot Module Replacement (HMR) and real-time UI synchronization at `http://localhost:5173`. |
| **Production** | Orchestrates a Secure Custom Protocol (`app://`) to serve optimized static assets, ensuring seamless SPA client-side routing via an intelligent `index.html` fallback mechanism. |
---
@@ -37,22 +39,22 @@ pnpm package:desktop
```
apps/desktop/
├── docs/ # Documentation
│ ├── CONFIGURATION.md # Target app, routing, HashRouter fallback
│ ├── AUTO_UPDATER.md # Release process, CI/CD, code signing
│ └── IPC_ARCHITECTURE.md # Security model, adding new features
├── docs/ # Architecture & Operations Documentation
│ ├── CONFIGURATION.md # Target app switching, routing fallback procedures
│ ├── AUTO_UPDATER.md # Release lifecycle, CI/CD, code signing
│ └── IPC_ARCHITECTURE.md # Security model, extensibility patterns
├── scripts/
│ └── copy-web-dist.ts # Prebuild: copies web app build → web-dist/
│ └── copy-web-dist.ts # Prebuild bridge: syncs web build → web-dist/
├── src/
│ ├── main/
│ │ └── index.ts # Main process: protocol, CORS, IPC, updater
│ │ └── index.ts # Main process: protocol, CORS, IPC, updater
│ ├── preload/
│ │ └── index.ts # Secure contextBridge API
│ │ └── index.ts # Secure contextBridge API surface
│ └── renderer/
│ └── index.html # Renderer shell (CSP reference)
├── .env # Target app configuration
├── electron-builder.yml # Packaging & auto-update config
├── electron-vite.config.ts # Build config (main, preload, renderer)
│ └── index.html # Renderer shell
├── .env # Runtime configuration
├── electron-builder.yml # Packaging & auto-update provider config
├── electron-vite.config.ts # Three-target build config (main, preload, renderer)
├── package.json
├── tsconfig.json
├── tsconfig.main.json
@@ -64,64 +66,114 @@ apps/desktop/
## Scripts
### Development & Build
| Script | Description |
|---|---|
| `pnpm dev` | Start electron-vite dev server |
| `pnpm build` | Compile TypeScript → `out/` |
| `pnpm prebuild` | Copy target web app's `dist/``web-dist/` |
| `pnpm package` | Build + package for current platform |
| `pnpm package:win` | Package for Windows (NSIS) |
| `pnpm package:mac` | Package for macOS (DMG + ZIP) |
| `pnpm package:linux` | Package for Linux (AppImage) |
| `pnpm dev` | Launch the electron-vite development server with live reload |
| `pnpm build` | Compile main, preload, and renderer TypeScript modules `out/` |
| `pnpm prebuild` | Synchronize the target web app's build output via `scripts/copy-web-dist.ts` — copies `apps/<DESKTOP_TARGET_APP>/dist/``web-dist/`. Invoked automatically before `pnpm build`. |
| `pnpm preview` | Preview the compiled Electron app locally without generating a distributable |
### 🚀 Packaging & Distribution
To generate a production-ready installer, execute from **within `apps/desktop/`** or use the root-level `pnpm package:*` commands, which orchestrate the full pipeline automatically:
| Command | Platform | Output Artifact |
|---|---|---|
| `pnpm package` | Current OS | Detects host OS and builds accordingly |
| `pnpm package:mac` | macOS | `.dmg` and `.zip` (supports x64 & arm64) |
| `pnpm package:win` | Windows | `.exe` (NSIS Installer) |
| `pnpm package:linux` | Linux | `.AppImage` |
All artifacts are emitted to the `release/` directory.
> [!IMPORTANT]
> **Deterministic Build Pipeline**: All `package:*` commands strictly enforce a deterministic build pipeline: compiling web assets via Turborepo, synchronizing the output via the `prebuild` bridge (`node --import tsx scripts/copy-web-dist.ts`), and finally generating the native binary through `electron-builder`.
>
> **Running locally within `apps/desktop/`**: These scripts assume the web app has already been compiled. Either run `pnpm build --filter=web` beforehand, or use the root-level `pnpm package:*` commands which handle the complete orchestration.
> [!WARNING]
> **macOS Code Signing**: Distributable macOS builds with Auto-Update capability **require** an Apple Developer Certificate. Provide the following environment variables:
> ```bash
> CSC_LINK=<base64-encoded .p12 certificate>
> CSC_KEY_PASSWORD=<certificate password>
> APPLE_ID=<your apple id>
> APPLE_APP_SPECIFIC_PASSWORD=<app-specific password>
> APPLE_TEAM_ID=<team id>
> ```
> Without valid code signing, macOS Gatekeeper will quarantine the application and `electron-updater` will reject update payloads. See [docs/AUTO_UPDATER.md](docs/AUTO_UPDATER.md) for the complete requirements.
> [!NOTE]
> **Cross-Compilation Advisory**: It is strongly recommended to build for each platform on its native OS. Cross-compilation (e.g., producing `.dmg` on Linux) may fail due to platform-specific toolchain dependencies. For CI, leverage a matrix strategy:
> ```yaml
> strategy:
> matrix:
> os: [macos-latest, windows-latest, ubuntu-latest]
> runs-on: ${{ matrix.os }}
> ```
---
## Configuration
The target web app is configured via `.env`:
The target web application is configured via `.env`:
```env
DESKTOP_TARGET_APP=web
DESKTOP_DEV_SERVER_URL=http://localhost:5173
```
See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for details on switching target apps and routing fallbacks.
See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for comprehensive guidance on target app switching, protocol internals, and the HashRouter fallback procedure.
---
## Features
## Core Capabilities
### Custom `app://` Protocol
Serves the web app's static build with SPA routing support. Includes path traversal protection and CSP header injection.
### 🌐 Custom `app://` Protocol
### Hardware Printing
The React app can list printers and trigger print jobs via `window.electronAPI.getPrinters()` and `window.electronAPI.print()`.
Provides a secure file-serving layer with built-in **Path Traversal Protection** and automated **CSP Header Injection**. All requests to unknown paths are intelligently rerouted to `index.html`, enabling React Router to resolve routes client-side without blank screens or 404 errors.
### Auto-Update
Background update checks via GitHub Releases with download progress forwarding to the React UI. See [docs/AUTO_UPDATER.md](docs/AUTO_UPDATER.md).
### 🖨️ Hardware Bridge
### CORS Bypass
API requests from the `app://` origin are transparently handled by stripping non-standard Origin headers and injecting CORS response headers.
Enables granular control over system peripherals — such as printers — through an asynchronous IPC communication layer. The React app can enumerate connected printers and dispatch print jobs via `window.electronAPI.getPrinters()` and `window.electronAPI.print()`, all without exposing native APIs to the renderer.
### 🔄 Auto-Update Engine
A fully managed update lifecycle powered by `electron-updater`. Background download progress is forwarded in real-time to the React UI via IPC event subscriptions, enabling rich notification experiences. See [docs/AUTO_UPDATER.md](docs/AUTO_UPDATER.md).
### 🛡️ CORS Bypass Proxy
A transparent proxy mechanism that handles cross-origin requests by sanitizing non-standard `app://` and `file://` Origin headers on outgoing requests and injecting permissive CORS response headers on incoming responses — allowing seamless integration with cloud APIs without server-side configuration changes.
---
## Security
## Hardened Security Perimeter
- `contextIsolation: true` — preload runs in an isolated context
- `nodeIntegration: false` — no Node.js APIs in the renderer
- `sandbox: true` — Chromium sandbox enabled
- `webSecurity: true` — same-origin policy enforced
- Path traversal protection in the custom protocol handler
- CSP headers injected on all HTML responses
The Desktop Wrapper enforces a **hardened security perimeter**, strictly isolating the Node.js Main Process from the Renderer Context. Our architecture is built upon the principle of **Least Privilege**, ensuring that the web application only interacts with system hardware through a verified, secure IPC bridge.
See [docs/IPC_ARCHITECTURE.md](docs/IPC_ARCHITECTURE.md) for the full security model and how to safely extend the app.
| Setting | Value | Purpose |
|---|---|---|
| `contextIsolation` | `true` | Preload executes in a hermetically sealed JavaScript context |
| `nodeIntegration` | `false` | Zero Node.js API surface exposed to the renderer |
| `sandbox` | `true` | Chromium OS-level sandbox enforced |
| `webSecurity` | `true` | Same-origin policy strictly upheld |
**Defense-in-depth protections in `src/main/index.ts`**:
- **Path Traversal Guard** — The `app://` protocol handler validates all resolved file paths remain within the `web-dist/` boundary using `normalize()` + `startsWith()`. Traversal attempts like `app://-/../../etc/passwd` are met with `403 Forbidden`.
- **CSP Header Injection** — Content-Security-Policy headers are injected as HTTP response headers on every HTML response served by the custom protocol — not via a `<meta>` tag — ensuring they cannot be stripped or bypassed by injected scripts.
- **Origin Sanitization** — `session.defaultSession.webRequest` intercepts all outgoing requests, stripping `app://` / `file://` Origin headers to prevent backend CORS rejections.
- **Navigation Guard** — The `will-navigate` event intercepts and blocks all navigation attempts to URLs outside the `app://` protocol and the authorized dev server origin.
See [docs/IPC_ARCHITECTURE.md](docs/IPC_ARCHITECTURE.md) for the full security model, the Three-Step Bridge pattern, and guidance on safely extending the app with new native features.
---
## Documentation
| Document | Contents |
| Document | Scope |
|---|---|
| [CONFIGURATION.md](docs/CONFIGURATION.md) | Target app switching, `app://` protocol internals, HashRouter fallback procedure |
| [AUTO_UPDATER.md](docs/AUTO_UPDATER.md) | Release workflow, CI/CD variables, S3/generic provider switching, code signing |
| [IPC_ARCHITECTURE.md](docs/IPC_ARCHITECTURE.md) | Security model, Three-Step Bridge pattern, existing IPC channels, extension guide |
| [AUTO_UPDATER.md](docs/AUTO_UPDATER.md) | Release lifecycle, CI/CD variables, provider switching, code signing |
| [IPC_ARCHITECTURE.md](docs/IPC_ARCHITECTURE.md) | Security model, Three-Step Bridge pattern, existing IPC channels, extensibility guide |