Pitopi is a privacy-first, peer-to-peer chat platform where every connection is direct, encrypted, and ephemeral. Users authenticate with a 96-byte key file instead of passwords or personal information, and the server merely coordinates signaling, logging, and housekeeping while all media flows directly through WebRTC.
- Key-based sign-up/login:
GET /signupproduces a downloadable 96-byte.keytoken;POST /loginaccepts that token viamultipart/form-datato create or resume a user session. - WebRTC-powered calls: Socket.IO handles signaling (
call-user,send-answer,send-ice-candidate) so peers can instantly open an end-to-end encrypted channel. - Stories with expiration: Upload, view, and delete short-lived stories that vanish after 12 hours; server-side storage tracks viewers and broadcasts totals in real time.
- Security-first protections: IP rate limiting, brute-force tracking, reserved-name enforcement, periodic cleanup of stale tokens/connections, and Firebase logging for every major event.
- Profile & visibility controls: Users can update profile pictures, toggle visibility, and the online roster reflects hidden/busy status immediately.
- Open-source stack: TypeScript backend, static
app/frontend assets, and optional docs indocs/.
src/server.ts: Express + Socket.IO server entry point that servesapp/, loads auth routes, initializes Firebase, and wires socket event handlers.src/auth: Signup/login flow with token management, brute-force counters, rate limiting, and error logging helpers.src/socket: Socket.IO event handlers for auth, calls, stories, profile updates, cleanup, and Firebase logging hooks.src/config: Shared constants (timeouts, quotas, reserved names) and Firebase initialization.src/utils: Connection tracking, story aggregation, logging context helpers, and online user broadcasting.app/: Frontend UI (HTML/CSS/JS) that consumes Socket.IO events and delivers the user experience.docs/: Help and marketing assets for the static site.
- Node.js 18+ (see
engines.nodeinpackage.json). - Firebase service account credentials stored as
firebase-key.jsonin the project root (never commit this file). - npm (or another Node package manager) for installing dependencies.
git clone https://github.com/pitopichat/pitopi.git
cd pitopi
npm install- Place your Firebase service account JSON at
firebase-key.json(keep this secret). - Optionally set
PORTor other env vars before running the server (defaults to 3000).
npm run dev– runtsxdirectly againstsrc/server.tsfor fast iterations.npm run watch–ts-node-devwith automatic restarts on change.npm run build– compile TypeScript todist/and mirror static assets viascripts/copy-app.js.npm start– run the compiled server fromdist/src/server.jsfor production-like behavior.
GET /signup: rate-limited generation of a.keytoken with 64 bytes of randomness + 32 bytes of salt.POST /login: accepts a 96-byte file upload, hashes it, and ensures the user record exists in Firestore.- Socket.IO lifecycle events:
auth,stories-updated,call-user,send-answer,send-ice-candidate,connection-ended,update-profile-pic,ping,disconnect, etc. - Internal cleanup: tokens older than a week are pruned, stories expire after 12 hours, stale connections/timeouts cleaned hourly.
npm testcurrently exits with an error placeholder (no automated tests yet). Add Jest/Mocha suites before relying on this command.
- Run in a production environment with
NODE_ENV=productionand the Firebase credentials available. - Monitor the Firebase Realtime Database
LOG/...tree because every event writes there; adjust logging frequency if needed. - Tokens and story data are periodically cleaned via
CLEANUP_INTERVAL(seesrc/socket/events.ts); adjust those constants for heavier loads. - Ensure HTTPS (or a secure tunnel) in front of the server since it routes real user tokens.
- Fork the repo, create a feature branch, implement your change, and open a Pull Request.
- Keep TypeScript, modern JS, and Socket.IO idioms consistent with existing code.
- When adding features touching Socket.IO events, update
src/socket/events.ts, supportingutils, and Firebase logging. - Document any public API, route, or event change in
docs/or a new markdown file.
GPLv3 (GNU General Public License v3). See LICENSE for the full text and obligations.