156 lines
13 KiB
Markdown
156 lines
13 KiB
Markdown
# Windows desktop client
|
|
|
|
## Status and architecture
|
|
|
|
The desktop deliverable is a thin Electron shell that loads the unchanged `apps/web` bundle. In development it can load the bundled UI or a validated `--web-url=https://...`; in packaged builds the web assets are copied into `resources/web`. The shell provides first-run connection settings, safe backend URL persistence, reconnect/reload, external-link handling, and session/cache clearing without exposing secrets to renderer code.
|
|
|
|
Build the Windows installer/portable executable on a Windows-capable build host after installing dependencies:
|
|
|
|
```bash
|
|
npm install
|
|
npm run test
|
|
npm run verify
|
|
npm run build:win
|
|
```
|
|
|
|
Until one is selected and signed, do not describe an unsigned artifact as released. The source check is Chromium- and Windows-independent and is runnable from the repository root:
|
|
|
|
```powershell
|
|
node apps\desktop\scripts\smoke-desktop.mjs
|
|
```
|
|
|
|
The check is Chromium- and Windows-independent, verifies that all referenced web assets exist, confirms the desktop manifest covers local HTML assets, rejects a second UI copy, and compares the desktop route list with the web smoke harness. It is also runnable on Linux/macOS:
|
|
|
|
```bash
|
|
node apps/desktop/scripts/smoke-desktop.mjs
|
|
```
|
|
|
|
## Remote backend connection
|
|
|
|
The desktop client is a remote API client, not a local database or API server. Configure the web runtime object before packaging or at deployment time:
|
|
|
|
```js
|
|
window.__PROSPECT_CONFIG__ = Object.freeze({
|
|
apiBase: 'https://api.example.com',
|
|
assetVersion: 'phase-15'
|
|
});
|
|
```
|
|
|
|
- `apiBase` is the approved API origin; trailing `/` is accepted by the client and removed when building paths. An empty value uses the same origin, then the legacy `window.API_BASE`/`localStorage.prospect_api_base` fallback used by the web client.
|
|
- `assetVersion` is a cache-busting release label and is not a secret.
|
|
- Do not place API tokens, passwords, provider credentials, private keys, or session values in `config.js`, the manifest, the executable, logs, or installer metadata.
|
|
- The shell should provide network availability diagnostics and a retry path, but must not silently switch to another API origin.
|
|
- The API must be reachable over HTTPS in production. Local HTTP is suitable only for development (`http://127.0.0.1:8000` API and `http://127.0.0.1:8080` web server).
|
|
|
|
## Authentication and session behavior
|
|
|
|
The desktop uses the same login and session contract as web:
|
|
|
|
1. `POST /api/v1/auth/login` receives the email/password form over the configured origin.
|
|
2. Requests include `credentials: 'include'`; the API sets a server-side session cookie.
|
|
3. Startup calls `GET /api/v1/auth/me`. A `401` shows the login screen; it does not expose cached workspace data.
|
|
4. `401` from a protected request clears the dashboard and asks the user to sign in again. `403` remains an authorization/workspace denial.
|
|
5. Log out calls `POST /api/v1/auth/logout`, invalidates the server session, resets the form, and returns to login.
|
|
|
|
The shell must use the host's cookie jar/WebView profile, preserve cookies only for the configured origin, and provide a user-visible sign-out/clear-session operation. Never copy cookies into local storage, command-line arguments, crash reports, telemetry, or custom headers. A desktop session remains a bearer credential: lock the workstation, use OS account protection, and sign out on shared machines. Multi-factor authentication, password reset, and session administration are backend responsibilities; the current pilot does not claim those capabilities.
|
|
|
|
## Supported configuration
|
|
|
|
Supported desktop runtime configuration is intentionally limited to the two keys in the manifest: `apiBase` and `assetVersion`. Backend deployment configuration remains environment-only and is not desktop configuration:
|
|
|
|
- `APP_ENV`, `LOG_LEVEL`, `CORS_ORIGINS`, `API_PORT`, `WEB_PORT`, and `DATA_DIR` are deployment settings.
|
|
- Production requires `SESSION_SECRET` of at least 32 characters, supplied through a secret manager/protected environment.
|
|
- `BOOTSTRAP_ADMIN_EMAIL` and `BOOTSTRAP_ADMIN_PASSWORD` are one-time provisioning inputs; remove and rotate them after bootstrap.
|
|
- `AUTOMATED_OUTREACH_ENABLED` is rejected when enabled; the enforced default is `false`.
|
|
|
|
The desktop must not offer controls that imply it can override tenant authorization, source approval, rate limits, suppression, score/eligibility, AI policy, outreach, or backend safety settings. Those are server-enforced contracts.
|
|
|
|
## Security model
|
|
|
|
- The backend is the authority for authentication, authorization, tenant (`organization_id`) isolation, validation, audit records, suppression, pipeline transitions, job actions, and all safety gates.
|
|
- The desktop is an untrusted presentation client. Treat all responses, local files, clipboard content, and rendered prospect text as untrusted; preserve the web client's escaping and avoid adding privileged native bridges.
|
|
- The shell should expose only navigation and storage APIs required to render the web bundle. Disable arbitrary navigation, popups, downloads, file/system protocol access, script injection, and unrestricted native IPC unless separately reviewed.
|
|
- Do not grant the web content filesystem, process, registry, shell, camera, microphone, or credential-manager access by default. CSV preview is browser-local and is not an import or upload authority unless the server workflow explicitly confirms it.
|
|
- Keep the no-send boundary: no SMTP probing, provider calls, campaign creation, autonomous follow-up, or direct fetching of arbitrary target URLs from the desktop. A high score, AI suggestion, extracted contact, or approval does not authorize outreach.
|
|
- Production traffic must use HTTPS with certificate validation. Do not add a “trust all certificates” switch. Pinning, if considered, needs an operational rotation plan and is not currently required by this source contract.
|
|
|
|
## Windows build and release prerequisites
|
|
|
|
## Electron development and Windows packaging
|
|
|
|
Install Node.js 20+ and npm on Windows, then run these exact commands from PowerShell:
|
|
|
|
```powershell
|
|
cd <clone>\apps\desktop
|
|
npm install
|
|
npm run verify
|
|
```
|
|
|
|
Start the API in another PowerShell window, then start Electron in development mode:
|
|
|
|
```powershell
|
|
cd <clone>\apps\api
|
|
python app\main.py --host 127.0.0.1 --port 8000 --db $env:TEMP\prospects.db
|
|
|
|
# second window
|
|
cd <clone>\apps\desktop
|
|
npm run dev
|
|
```
|
|
|
|
`npm run dev` supplies the public runtime backend URL `http://127.0.0.1:8000`. For another environment, use `$env:PROSPECT_API_BASE="https://api.example.com"; npm start` (or the Connection settings menu). URLs are validated and credential/query/fragment-bearing values are rejected.
|
|
|
|
Build both x64 Windows artifacts only on Windows:
|
|
|
|
```powershell
|
|
cd <clone>\apps\desktop
|
|
npm install
|
|
npm run verify
|
|
npm run build:win
|
|
```
|
|
|
|
The NSIS installer and portable executable are written to `apps\desktop\release\`. This Linux checkout has not built, and does not claim to have built, an `.exe`.
|
|
|
|
## Auto-update policy
|
|
|
|
Auto-update is intentionally disabled until release signing, certificate custody, artifact publication, update-channel authorization, and rollback procedures are configured. There is no updater integration or publish provider in this package; do not add `electron-updater` or an update channel as part of a local build.
|
|
|
|
## API/CORS requirements
|
|
|
|
The renderer uses the existing web UI and sends credentialed requests to the configured API. Configure the API's `CORS_ORIGINS` for the exact origin emitted by the selected Electron loading strategy, with `Access-Control-Allow-Credentials: true`; never use `*` with credentials. Preserve server-side session, tenant authorization, CSRF, suppression, and outreach-disabled controls. CORS is not an authorization boundary. Verify preflight and authenticated login against staging before distribution.
|
|
|
|
A native desktop build packages `apps/web` unchanged via electron-builder `extraResources`; it does not modify backend files or create a second UI implementation.
|
|
|
|
A native release is blocked until the shell is selected and its toolchain is pinned. The release builder must provide:
|
|
|
|
- Supported Windows 10/11 x64 baseline, a clean build VM, and a documented x64/arm64 decision.
|
|
- Pinned Node.js LTS and package-lock (if the selected shell uses Node), plus the selected shell's exact SDK/toolchain and WebView2 runtime policy.
|
|
- Reproducible web asset build, manifest/version update, route/asset smoke check, JSON parse, JavaScript syntax check, and a clean `git diff --check`.
|
|
- Clean-room install/run test with the real signed artifact, login/session expiry/logout checks, offline/API-unavailable behavior, HTTPS certificate failure behavior, and DPI/scaling/high-contrast/basic keyboard navigation checks.
|
|
- Release notes containing API compatibility, minimum Windows version, architecture, config origin, known limitations, and rollback/revocation instructions.
|
|
- Artifact hashes and the exact source commit recorded beside the installer/MSIX/portable artifact. Retain the previous known-good artifact for rollback.
|
|
|
|
The API and web deployment still require their existing Docker/Compose, TLS, secret, backup, monitoring, and operational prerequisites. Building a Windows client does not deploy or upgrade the remote backend.
|
|
|
|
## Code signing and distribution
|
|
|
|
Every distributed `.exe`, `.msi`, MSIX package, and updater must be Authenticode-signed with an organization-controlled code-signing certificate. Prefer an EV/managed key or a hardware-backed/CI signing service; never commit a private key or export it into a developer workspace. Verify the signature and timestamp on a clean Windows host (for example with `Get-AuthenticodeSignature`) before publication. Sign each embedded executable and installer payload as required by the selected packaging technology, publish SHA-256 checksums, and retain signing/audit records. Unsigned developer builds must be clearly labeled and must never use the production API origin by default.
|
|
|
|
Certificate rotation, revocation, compromised-builder response, SmartScreen reputation, update-channel authorization, and artifact rollback require an owner and runbook before release. Signing proves publisher integrity; it does not make the client trusted with tenant data or make a backend response authoritative.
|
|
|
|
## Firewall and CORS
|
|
|
|
The desktop makes outbound HTTPS connections to the configured API; it does not listen for inbound connections and should not require an inbound Windows Firewall rule. If a chosen shell starts a local callback/update server, bind it to loopback, use an ephemeral port, authenticate the callback, and document the narrowly scoped firewall exception. Never open the API or a development server to `0.0.0.0` for desktop distribution.
|
|
|
|
For a remote API origin, configure `CORS_ORIGINS` to the exact desktop origin emitted by the selected shell/runtime and keep `Access-Control-Allow-Credentials: true`. Do not use `*` with credentialed requests. The API currently returns the configured `CORS_ORIGINS` value and allows `Content-Type`; verify the selected WebView's origin and preflight behavior in a staging environment. If the shell loads `file://` or a custom `app://` origin, do not guess a CORS value: choose a reviewed HTTPS/custom-origin strategy or package the UI behind the same approved origin, because cookie and CORS behavior differs by WebView host.
|
|
|
|
CORS is not authentication or tenant isolation. The backend must continue to enforce sessions and organization scope even when a request appears to come from the desktop.
|
|
|
|
## Limitations and support boundary
|
|
|
|
- The native Electron Windows shell and packaging configuration are checked in, but no signed Windows installer or portable `.exe` is included in this source checkout.
|
|
- The desktop has the web client's pilot limitations: SQLite/in-process jobs are not durable or horizontally scalable; SSE, live external discovery, production DNS/availability, production egress isolation, and production outreach delivery are not implemented.
|
|
- The current password fallback is development-grade; production still requires Argon2id, MFA, CSRF protection, rate limiting, durable audit/retention, and tested backup/restore procedures.
|
|
- Network loss, API version skew, expired sessions, proxy policy, certificate interception, sleep/resume, and WebView runtime updates can affect the client. The desktop cannot repair backend data or bypass a blocked safety gate.
|
|
- Local UI assets may be cached by the selected shell; bump `assetVersion` and require a restart/refresh after a UI release. There is no service-worker migration or offline write queue.
|
|
- CSV remains preview-only, and no desktop feature changes the no-send default. See `apps/web/README.md`, `apps/api/README.md`, `docs/SECURITY.md`, and `docs/RELEASE_CHECKLIST.md` for the authoritative web/API safety and operations contracts.
|