# Desktop 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. --- ## Quick Start ```bash # From the monorepo root # Install dependencies pnpm install # Development (starts both the web dev server and Electron) pnpm dev:desktop # Build for production pnpm build:desktop # Package for distribution pnpm package:desktop ``` --- ## How It Works | Environment | Operational Logic | |---|---| | **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. | --- ## Project Structure ``` apps/desktop/ ├── 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 bridge: syncs web build → web-dist/ ├── src/ │ ├── main/ │ │ └── index.ts # Main process: protocol, CORS, IPC, updater │ ├── preload/ │ │ └── index.ts # Secure contextBridge API surface │ └── 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 ├── tsconfig.preload.json └── tsconfig.renderer.json ``` --- ## Scripts ### Development & Build | Script | Description | |---|---| | `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//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= > CSC_KEY_PASSWORD= > APPLE_ID= > APPLE_APP_SPECIFIC_PASSWORD= > APPLE_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 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 comprehensive guidance on target app switching, protocol internals, and the HashRouter fallback procedure. --- ## Core Capabilities ### 🌐 Custom `app://` Protocol 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. ### 🖨️ Hardware Bridge 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. ### 🔒 Single Instance Lock & Data Integrity The application enforces a **single running instance** via `app.requestSingleInstanceLock()`. If a user attempts to launch a second instance, the duplicate process is terminated immediately and the existing window is restored and focused. This mechanism serves two critical purposes: - **Data Integrity**: Prevents race conditions and write conflicts in local databases (IndexedDB/PouchDB) that could arise from concurrent access by multiple Electron processes. - **Resource Efficiency**: Avoids duplicate memory allocation, IPC handler registration, and protocol handler conflicts. --- ## Hardened Security Perimeter 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. | 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 `` 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 | Scope | |---|---| | [CONFIGURATION.md](docs/CONFIGURATION.md) | Target app switching, `app://` protocol internals, HashRouter fallback procedure | | [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 |