{"id":26506542,"url":"https://github.com/fabiconcept/secret-room-backend","last_synced_at":"2025-10-10T02:08:13.252Z","repository":{"id":281144540,"uuid":"943894330","full_name":"fabiconcept/secret-room-backend","owner":"fabiconcept","description":"A secure, lightweight Node.js server handling encrypted messaging, file sharing, custom usernames, and self-destructing servers.","archived":false,"fork":false,"pushed_at":"2025-05-23T22:55:17.000Z","size":7251,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-23T23:32:10.163Z","etag":null,"topics":["anonymous","anonymous-chat","chat-app","secret-room"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fabiconcept.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-06T12:48:45.000Z","updated_at":"2025-05-23T22:55:20.000Z","dependencies_parsed_at":"2025-04-08T21:24:13.354Z","dependency_job_id":"0ea72d00-33b4-41f4-acbb-39c6e4b43a44","html_url":"https://github.com/fabiconcept/secret-room-backend","commit_stats":null,"previous_names":["fabiconcept/secret-room-backend"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fabiconcept/secret-room-backend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiconcept%2Fsecret-room-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiconcept%2Fsecret-room-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiconcept%2Fsecret-room-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiconcept%2Fsecret-room-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fabiconcept","download_url":"https://codeload.github.com/fabiconcept/secret-room-backend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiconcept%2Fsecret-room-backend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002527,"owners_count":26083399,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anonymous","anonymous-chat","chat-app","secret-room"],"created_at":"2025-03-20T22:37:51.789Z","updated_at":"2025-10-10T02:08:13.247Z","avatar_url":"https://github.com/fabiconcept.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Project Snapshot](https://github.com/fabiconcept/secret-room-backend/blob/main/image.png)\n# 🕵️‍♂️ Secret Room - Backend\n\n\u003cdiv align=\"center\" style=\"maargin: 2rem 0;\"\u003e\n  \u003cdiv\u003e\n    \u003cimg src=\"https://img.shields.io/badge/last_commit-last_friday-blue?style=flat-square\u0026logo=git\" alt=\"Last Commit\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/typescript-100.0%25-blue?style=flat-square\u0026logo=typescript\" alt=\"TypeScript Usage\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/languages-1-blue?style=flat-square\" alt=\"Languages\" /\u003e\n  \u003c/div\u003e\n\n  \u003ch2\u003eBuilt with these tools and technologies:\u003c/h2\u003e\n\n  \u003cdiv\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Express-black?style=flat-square\u0026logo=express\" alt=\"Express\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-JSON-black?style=flat-square\u0026logo=json\" alt=\"JSON\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Socket.io-black?style=flat-square\u0026logo=socket.io\" alt=\"Socket.io\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-npm-cb3837?style=flat-square\u0026logo=npm\" alt=\"npm\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Mongoose-red?style=flat-square\u0026logo=mongodb\" alt=\"Mongoose\" /\u003e\n  \u003c/div\u003e\n  \n  \u003cdiv\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-.ENV-ECD53F?style=flat-square\u0026logo=dotenv\" alt=\".ENV\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Nodemon-76D04B?style=flat-square\u0026logo=nodemon\" alt=\"Nodemon\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-TypeScript-3178C6?style=flat-square\u0026logo=typescript\" alt=\"TypeScript\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-ts--node-3178C6?style=flat-square\u0026logo=ts-node\" alt=\"ts-node\" /\u003e\n    \u003cimg src=\"https://img.shields.io/badge/-Socket-8A2BE2?style=flat-square\u0026logo=socket.io\" alt=\"Socket\" /\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\n**Secret Room** is a fully anonymous, real-time chat web app that lets users create temporary servers and invite others to chat without ever revealing their identity. This is the backend service powering the chat experience, built with **Node.js**, **Express**, **MongoDB**, and **Socket.io**.\n\n\u003e 💡 This is my first personal Node.js backend project. It focuses heavily on secure communication, temporary server lifecycles, and anonymous user management.\n\n---\n\n## 🚀 Features\n\n- 🔒 JWT Authentication for secure access  \n- 🧠 Anonymous user identification via fingerprinting  \n- 💬 Real-time chat between host and guests (powered by Socket.io)  \n- ⚡ Instant join/leave/typing notifications  \n- ⏳ Self-destructing servers based on a lifespan  \n- 📨 Global \u0026 Unique server invitation system  \n- 👻 Deterministic anonymous usernames per server  \n- 📦 Clean modular structure: Models, Routes, Controllers, Middleware  \n\n---\n\n## 📁 Project Structure\n\n```\n.\n├── controllers/\n│   ├── userController.js\n│   ├── serverController.js\n│   └── messagesController.js\n├── middleware/\n│   └── authenticateJWT.js\n├── models/\n│   ├── User.js\n│   ├── Server.js\n│   ├── Message.js\n│   └── Invitation.js\n├── socket/\n│   └── socketHandler.js\n├── routes/\n│   └── ...\n```\n\n---\n\n## 📦 Tech Stack\n\n- **Node.js**\n- **Express**\n- **MongoDB** (Mongoose)\n- **Socket.io** for real-time communication\n- **JWT** for authentication\n- **UUID + Custom Encryption** for anonymous ID and secure communication\n\n---\n\n## 🔐 Authentication\n\n- Uses JWT tokens to secure private routes  \n- Fingerprinting used to generate a unique ID for users (without collecting sensitive info)  \n\n---\n\n## 💬 Real-time Communication (Socket.io)\n\n- Users join a room corresponding to the serverId  \n- On joining, a deterministic **anonymous username** is generated using a `serverId-userId` combo (see below)  \n- Events include:\n  - `user:join` – Notify server members of a new user\n  - `user:leave` – Broadcast when a user disconnects\n  - `user:active` - Broadcast when the user is active\n  - `server:deleted` - Broadcast when the server is deleted\n  - `message:send` – Relay messages between users\n  - `message:read` – Relay messages between users\n- Socket connections are JWT-authenticated and scoped to server rooms\n\n---\n\n## 👻 Username Generation (Anonymity)\n\nUsernames are deterministically generated per server using a salted pattern based on the combination: `serverId-userId`.\n\n```ts\n// utils/generateUsername.ts\nexport function generateUsername(salt: string): string {\n  // uses custom hash + either consonant-vowel or alphanumeric pattern\n}\n```\n\n### Why this matters:\n- Ensures each user has a **unique, anonymous identity** _per server_  \n- Zero chance of real user data leaks  \n- No usernames are ever reused across different servers  \n\n---\n\n## 🧪 API Endpoints\n\n### 🔐 Authentication Required\n\n| Method | Endpoint |\n|--------|----------|\n| `POST` | `/` – Create a new server |\n| `POST` | `/invitation/:globalInvitationId` – Join with a global invite |\n| `POST` | `/unique-invitation/:inviteCode` – Join with a unique invite |\n| `GET`  | `/:serverId` – Get server data |\n| `GET`  | `/:serverId/active-users` – Get current active users |\n| `GET`  | `/:serverId/generate-unique-server-invitation-id` – Generate a unique invite |\n| `GET`  | `/:serverId/messages` – Fetch messages in the server |\n| `DELETE` | `/:serverId` – Delete a server |\n\n---\n\n## 🧬 Mongoose Models\n\n### 🧑‍💻 User\n```ts\nuserId, isOnline, lastSeen, currentServer, createdAt, bgColor, textColor\n```\n\n### 💬 Message\n```ts\nserverId, senderId, receiverId, content, attachmentUrl, sent, readBySender, readByReceiver\n```\n\n### 🏠 Server\n```ts\nserverId, owner, serverName, salt, globalInvitationId, expiresAt, approvedUsers, allUsers\n```\n\n### 🎟️ Invitation\n```ts\ninviteCode, used, serverId, expiresAt\n```\n\n---\n\n## ⚙️ Setup Instructions\n\n```bash\n# 1. Clone the repo\ngit clone [https://github.com/your-username/secret-room-backend](https://github.com/fabiconcept/secret-room-backend.git)\n\n# 2. Navigate into the folder\ncd secret-room-backend\n\n# 3. Install dependencies\nnpm install\n\n# 4. Create a `.env` file and add:\n# PORT\n# HOST\n# CORS_ORIGIN\n# JWT_SECRET\n# MONGODB_URI\n# API_KEY\n\n# 5. Run the server\nnpm run dev\n```\n\n\n---\n\n## 🙌 Author\n\nMade with ❤️ by [Favour Tochukwu Ajokubi](https://github.com/FavourBE)\n\n---\n\n## 🛡️ License\n\nThis project is open-source and available under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabiconcept%2Fsecret-room-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffabiconcept%2Fsecret-room-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabiconcept%2Fsecret-room-backend/lists"}