# 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. ## 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`. - `CORS_ORIGIN`: Optional allowed browser origin. If omitted, the server reflects request origins. - `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.