Files

107 lines
5.3 KiB
Markdown
Raw Permalink Normal View History

2026-03-09 19:35:08 +01:00
# PrivateChat
PrivateChat is a two-part application:
- An Angular 21 + Bootstrap frontend for authentication, peer discovery, and direct chat.
- A Fastify + WebSocket backend for JWT-based authentication, Redis-backed sessions, and initial WebRTC signaling.
Once two clients discover each other through the backend, text, JSON payloads, and file transfers move over a direct WebRTC data channel. Signaling is only allowed for clients with an active authenticated backend session.
## Features
- Register and log in with JWTs that are bound to active Redis sessions.
- Sign in with either a password or a registered WebAuthn access key.
- Persist users in a local SQLite database with encrypted credential storage.
- Persist the JWT signing secret in the SQLite database, encrypted at rest.
- Allow authenticated users to register multiple WebAuthn access keys.
- Discover online peers through a signaling WebSocket.
- Establish direct WebRTC peer connections.
- Exchange plain text messages, structured JSON payloads, and files.
- Keep signaling on the backend and user content on the peer-to-peer data channel.
## Run locally
Requirements:
- Node.js 20+ recommended.
- npm 10+.
- A local Redis instance reachable at `redis://127.0.0.1:6379/0` by default.
Install the root runner dependency:
```bash
npm install
```
Start both apps:
```bash
npm run dev
```
Configuration defaults now live in the repo root [`.env`](/var/approot/PrivateChat/.env). The backend loads that file with `dotenv` at startup, and the frontend generates `client/public/env.js` from the same file before `ng serve` and `ng build`.
To serve the prebuilt Angular app from Fastify and run only one server:
```bash
npm run build
npm run start --prefix server
```
The backend serves `client/dist/client/browser` on the same origin as the API and WebSocket endpoints.
Default endpoints:
- Frontend: `http://localhost:4200`
- Backend: `http://localhost:3000`
The backend automatically creates:
- `server/data/privatechat.sqlite` for users and encrypted secret material.
- `server/data/master.key` if `PRIVATECHAT_MASTER_KEY` is not supplied.
The frontend lets you override the backend URL from the login screen if you need a different host or port.
## Apple client
The repo also includes a multiplatform SwiftUI client in `apple-client/` for macOS and iOS/iPadOS.
- The native Settings UI manages backend URL, password auth, passkey auth, and access-key registration.
- The main chat surface embeds the Angular client bundle in a WKWebView, so the WebRTC chat workspace stays aligned with the web app.
- Generate the Xcode project with `xcodegen generate --spec apple-client/project.yml --project-root apple-client`.
- A build of the Apple app automatically rebuilds the Angular client into `apple-client/WebApp/` before bundling it.
2026-03-10 04:13:32 +01:00
The backend also exposes the latest Angular browser build through an API that native clients can sync into their local `WKWebView` bundle cache:
- `GET /api/web-app/manifest`: Returns a bundle manifest with a stable `bundleId`, latest `generatedAt` timestamp, and a file list containing relative paths, SHA-256 hashes, MIME types, sizes, and download URLs.
- `GET /api/web-app/files/<relative-path>`: Streams an individual file from `client/dist/client/browser` with `ETag` and `Last-Modified` headers for native caching.
If the Angular build does not exist yet, those endpoints return `404`.
2026-03-09 19:35:08 +01:00
## Backend environment
The backend accepts these environment variables:
- `PORT`: HTTP and WebSocket port. Default `3000`.
- `REDIS_URL`: Local Redis connection string. Default `redis://127.0.0.1:6379/0`.
- `SESSION_TTL_SECONDS`: Redis session TTL. Default `43200`.
- `SQLITE_PATH`: Optional SQLite database path.
- `PRIVATECHAT_DATA_DIR`: Base directory for generated local storage.
- `PRIVATECHAT_MASTER_KEY`: Optional master key for encrypting SQLite secret material and user credentials.
- `PRIVATECHAT_MASTER_KEY_PATH`: Optional file path for the generated master key.
- `PRIVATECHAT_WEB_DIST_DIR`: Directory containing the prebuilt Angular browser bundle. Default `client/dist/client/browser`.
2026-03-10 02:49:27 +01:00
- `CORS_ORIGIN`: Optional comma-separated browser-origin allowlist. If omitted, the server accepts request origins. The special `null` origin from embedded `file://` webviews is accepted.
2026-03-09 19:35:08 +01:00
- `WEBAUTHN_ORIGIN`: Browser origin allowed to register access keys. Default `http://localhost:4200`.
- `WEBAUTHN_RP_ID`: WebAuthn RP ID. Default hostname of `WEBAUTHN_ORIGIN`.
- `WEBAUTHN_RP_NAME`: Friendly RP name for browser access-key prompts. Default `PrivateChat`.
- `WEBAUTHN_USER_VERIFICATION`: WebAuthn user-verification policy for access-key registration. Supported values: `discouraged`, `preferred`, `required`. Default `preferred`.
- `WEBAUTHN_CHALLENGE_TTL_SECONDS`: Pending access-key registration challenge TTL in Redis. Default `300`.
## Frontend environment
- `PRIVATECHAT_CLIENT_SERVER_URL`: Default backend URL preloaded into the Angular app before local storage overrides apply.
## Production note
This project uses the Fastify server only for auth and signaling. The chat payload itself stays peer-to-peer over WebRTC. For production deployment, replace the local master key strategy with your preferred secret-management system, keep Redis durable enough for your session policy, and configure TURN infrastructure if peers cannot connect with STUN alone.