{"id":49245352,"url":"https://github.com/mewisme/private-chats","last_synced_at":"2026-04-24T21:30:40.882Z","repository":{"id":303049582,"uuid":"1014239648","full_name":"mewisme/private-chats","owner":"mewisme","description":"Real-time anonymous 1-on-1 chat app using Next.js 15, Firebase, Tailwind CSS, and Zustand.","archived":false,"fork":false,"pushed_at":"2025-07-13T11:19:21.000Z","size":575,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-13T11:32:22.556Z","etag":null,"topics":["1-on-1","chat","firebase","firestore","nextjs","private","simple"],"latest_commit_sha":null,"homepage":"https://chat.mewis.me","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mewisme.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-05T10:18:01.000Z","updated_at":"2025-07-13T11:19:24.000Z","dependencies_parsed_at":"2025-07-05T11:51:32.529Z","dependency_job_id":null,"html_url":"https://github.com/mewisme/private-chats","commit_stats":null,"previous_names":["mewisme/private-chats"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mewisme/private-chats","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mewisme%2Fprivate-chats","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mewisme%2Fprivate-chats/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mewisme%2Fprivate-chats/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mewisme%2Fprivate-chats/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mewisme","download_url":"https://codeload.github.com/mewisme/private-chats/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mewisme%2Fprivate-chats/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32241490,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T13:21:15.438Z","status":"ssl_error","status_checked_at":"2026-04-24T13:21:15.005Z","response_time":64,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["1-on-1","chat","firebase","firestore","nextjs","private","simple"],"created_at":"2026-04-24T21:30:39.502Z","updated_at":"2026-04-24T21:30:40.872Z","avatar_url":"https://github.com/mewisme.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Private Chats\n\nA modern real-time anonymous chat application with dual-mode functionality - chat with AI or connect with strangers anonymously. Built with Next.js 15, Firebase, and using the Gemini API for AI responses.\n\n## 🚀 Features\n\n### Multi-Tab Synchronization\n- **🔄 Route Sync**: All browser tabs automatically navigate to the same route as the first tab\n- **⚡ Real-time Message Sync**: Messages sent in one tab instantly appear in all other tabs\n- **⚙️ Settings Sync**: Settings changes in one tab are immediately reflected in all other tabs\n- **💾 Cache Sync**: Application state and cache changes are synchronized across all tabs\n- **📡 Cross-Tab Communication**: Uses BroadcastChannel API with localStorage fallback for seamless synchronization\n- **🛡️ Infinite Loop Protection**: Smart navigation logic prevents redirect loops between tabs\n\n### Dual-Mode Chat System\n- **🤖 AI Chat Mode**: Intelligent conversations using Gemini 2.5 Flash API\n- **👥 Anonymous Stranger Chat**: Real-time anonymous 1-on-1 conversations\n- **⚙️ Settings Toggle**: Easy switching between chat modes\n\n### Core Functionality\n- **Real-time Messaging**: Instant message delivery using Firebase Firestore\n- **Anonymous Matching**: Automatic pairing with available strangers\n- **Room Management**: Automatic room creation, joining, and cleanup\n- **Session Persistence**: Client-based session management without authentication\n- **Message History**: Temporary message storage during active sessions\n\n### User Experience\n- **Clean Monochrome Design**: Minimalist black, white, and gray aesthetic\n- **Dark/Light Mode**: System-aware theme switching\n- **Responsive Design**: Optimized for all device sizes\n- **Auto-focus Input**: Seamless typing experience\n- **Loading States**: Visual feedback during operations\n- **Toast Notifications**: Real-time status updates\n\n### Technical Features\n- **TypeScript**: Full type safety throughout the application\n- **Real-time Updates**: Live message synchronization\n- **Multi-Tab Sync**: Cross-tab communication using BroadcastChannel API\n- **Error Boundaries**: Graceful error handling and recovery\n- **PWA Support**: Progressive Web App capabilities\n- **Automatic Cleanup**: Scheduled removal of inactive rooms and messages\n\n## 🛠️ Tech Stack\n\n### Frontend\n- **[Next.js 15](https://nextjs.org/)** - React framework with App Router\n- **[TypeScript](https://www.typescriptlang.org/)** - Type-safe JavaScript\n- **[Tailwind CSS](https://tailwindcss.com/)** - Utility-first CSS framework\n- **[Radix UI](https://www.radix-ui.com/)** - Accessible component primitives\n- **[Zustand](https://github.com/pmndrs/zustand)** - Lightweight state management\n- **[Framer Motion](https://www.framer.com/motion/)** - Animation library\n\n### Backend \u0026 Database\n- **[Firebase Firestore](https://firebase.google.com/docs/firestore)** - Real-time NoSQL database\n- **[Gemini AI API](https://ai.google.dev/)** - AI chat responses via API\n- **[Vercel](https://vercel.com/)** - Deployment and hosting\n\n### Development Tools\n- **[ESLint](https://eslint.org/)** - Code linting\n- **[Prettier](https://prettier.io/)** - Code formatting\n- **[pnpm](https://pnpm.io/)** - Package manager\n- **[Turbopack](https://turbo.build/pack)** - Fast development bundler\n\n## 📁 Project Structure\n\n```\nsrc/\n├── app/                    # Next.js App Router\n│   ├── (home)/            # Home page group\n│   │   └── page.tsx       # Landing page with mode selection\n│   ├── chat/              # Chat routes\n│   │   ├── [roomId]/      # Dynamic stranger chat rooms\n│   │   │   └── page.tsx   # Stranger chat page\n│   │   └── ai/            # AI chat route\n│   │       └── page.tsx   # AI chat page\n│   ├── api/               # API routes\n│   │   ├── ai/            # AI chat endpoint\n│   │   │   └── route.ts   # Gemini API integration\n│   │   └── cleanup/       # Room cleanup endpoint\n│   │       └── route.ts   # Scheduled cleanup job\n│   ├── layout.tsx         # Root layout with providers\n│   └── manifest.ts        # PWA manifest\n├── components/            # UI components\n│   ├── ui/               # shadcn/ui components\n│   ├── chat/             # Chat-specific components\n│   │   ├── chat-room.tsx # Main chat interface\n│   │   ├── chat-input.tsx # Message input component\n│   │   ├── chat-message-list.tsx # Message display\n│   │   └── chat-leave.tsx # Leave chat button\n│   ├── common/           # Shared components\n│   │   ├── app-header.tsx # Application header\n│   │   ├── loading.tsx   # Loading states\n│   │   └── settings/     # Settings dialog\n│   ├── providers/        # Context providers\n│   │   ├── theme-provider.tsx # Theme management\n│   │   └── error-boundary.tsx # Error handling\n│   └── base/            # Base components\n│       └── logo.tsx     # Application logo\n├── lib/                  # Core utilities\n│   ├── firebase.ts      # Firebase configuration\n│   ├── room.ts          # Room management logic\n│   ├── message.ts       # Message handling\n│   └── typing.ts        # Typing indicators\n├── hooks/               # Custom React hooks\n│   ├── use-cache-store.ts # Client state management\n│   ├── use-settings.ts   # Settings management\n│   ├── use-client.ts     # Client-side utilities\n│   └── use-notifications.ts # Notification system\n├── utils/               # Utility functions\n│   ├── ai-chat.ts       # AI chat utilities\n│   └── index.ts         # Common utilities\n└── styles/              # Global styles\n    └── globals.css      # Tailwind CSS configuration\n```\n\n## 🔄 Multi-Tab Synchronization\n\nPrivate Chats features advanced multi-tab synchronization that ensures a seamless experience across multiple browser tabs:\n\n### How It Works\n- **Route Synchronization**: When you navigate to a new chat room in one tab, all other tabs automatically follow to the same route\n- **Message Synchronization**: Messages sent or received in any tab are instantly reflected in all other open tabs\n- **Settings Synchronization**: Changes to app settings (AI mode, markdown, etc.) in one tab are immediately applied to all other tabs\n- **Cache Synchronization**: Application state including client ID, room ID, and session data is kept consistent across all tabs\n- **State Consistency**: Chat state, including typing indicators and connection status, is kept consistent across tabs\n\n### Technical Implementation\n- **Primary Method**: Uses the modern `BroadcastChannel` API for efficient cross-tab communication\n- **Fallback Support**: Automatically falls back to `localStorage` events for older browsers\n- **Loop Prevention**: Smart timestamping and duplicate detection prevents infinite redirect loops\n- **Performance Optimized**: Minimal overhead with event-driven architecture\n\n### User Experience Benefits\n- **Multi-tasking**: Work in multiple tabs without losing context\n- **Instant Updates**: No need to refresh or switch tabs to see new messages\n- **Consistent Settings**: Settings changes are immediately reflected across all tabs\n- **Seamless State**: Application state remains consistent regardless of which tab you're using\n- **Consistent Navigation**: All tabs stay in sync when moving between chat rooms\n- **Seamless AI Chat**: AI conversations are synchronized across all tabs in real-time\n- **Persistent Sessions**: Client sessions and room connections are maintained across all tabs\n\n## 🚀 Getting Started\n\n### Prerequisites\n\n- **Node.js 18+** and **pnpm 10+**\n- **Firebase Account** - [Firebase Console](https://console.firebase.google.com/)\n- **Google AI Studio Account** - [AI Studio](https://makersuite.google.com/app/apikey)\n\n### 1. Clone the Repository\n\n```bash\ngit clone https://github.com/mewisme/private-chats.git\ncd private-chats\n```\n\n### 2. Install Dependencies\n\n```bash\npnpm install\n```\n\n### 3. Firebase Setup\n\n1. **Create a Firebase Project**\n   - Go to [Firebase Console](https://console.firebase.google.com/)\n   - Create a new project or select existing one\n   - Enable Firestore Database in \"test mode\" for development\n\n2. **Get Firebase Configuration**\n   - Go to Project Settings → General → Your apps\n   - Click \"Add app\" and select \"Web\"\n   - Copy the Firebase config object\n\n3. **Set up Firestore Security Rules** (for production)\n   ```javascript\n   rules_version = '2';\n   service cloud.firestore {\n     match /databases/{database}/documents {\n       match /{document=**} {\n         allow read, write: if request.time \u003c timestamp.date(2024, 12, 31);\n       }\n     }\n   }\n   ```\n\n### 4. Gemini AI Setup\n\n1. **Get API Key**\n   - Go to [Google AI Studio](https://makersuite.google.com/app/apikey)\n   - Create a new API key\n   - Copy the key for environment configuration\n\n### 5. Environment Configuration\n\nCreate a `.env.local` file in the root directory:\n\n```bash\n# Firebase Configuration\nNEXT_PUBLIC_FIREBASE_API_KEY=your_firebase_api_key\nNEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com\nNEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id\nNEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_project.appspot.com\nNEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_sender_id\nNEXT_PUBLIC_FIREBASE_APP_ID=your_app_id\nNEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=your_measurement_id\n\n# Gemini AI Configuration\nSERVER_GEMINI_API_KEY=your_SERVER_GEMINI_API_KEY\n\n# Server Configuration (optional)\nSERVER_CRON_SECRET=your_secure_random_string\n```\n\n### 6. Start Development Server\n\n```bash\npnpm dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000) in your browser.\n\n## 📖 Usage Guide\n\n### AI Chat Mode\n\n1. **Enable AI Mode**\n   - Click the settings icon (⚙️) in the header\n   - Toggle \"AI Mode\" to ON\n   - Close the settings dialog\n\n2. **Start AI Chat**\n   - Click \"Chat with AI\" on the home page\n   - Begin typing to start a conversation\n   - The AI responds in real-time via Gemini 2.5 Flash API\n\n3. **AI Features**\n   - Contextual conversations with memory\n   - Markdown support for formatted responses\n   - Instant response generation\n   - Private conversation history\n\n### Anonymous Stranger Chat\n\n1. **Disable AI Mode**\n   - Ensure AI Mode is OFF in settings\n   - This enables stranger chat functionality\n\n2. **Find a Chat Partner**\n   - Click \"Find Stranger\" on the home page\n   - System will either:\n     - Connect you instantly if someone is waiting\n     - Put you in a waiting room for others to find\n\n3. **Chat Experience**\n   - Completely anonymous - no registration required\n   - Real-time message delivery\n   - Typing indicators\n   - Leave anytime with the \"Leave Chat\" button\n\n### Settings Configuration\n\nAccess settings via the gear icon (⚙️) in the header:\n\n- **AI Mode**: Toggle between AI and stranger chat\n- **Allow Markdown**: Enable markdown formatting in messages\n- **Link Preview**: Show previews for shared links\n- **Theme**: Switch between light, dark, and system themes\n\n## 🔧 Development\n\n### Available Scripts\n\n```bash\n# Development\npnpm dev              # Start development server with Turbopack\npnpm build           # Build for production\npnpm start           # Start production server\n\n# Code Quality\npnpm lint            # Run ESLint\npnpm lint:fix        # Fix ESLint issues\npnpm format          # Format code with Prettier\npnpm format:check    # Check code formatting\n```\n\n### API Endpoints\n\n**🔒 Security**: All API endpoints require valid origin headers from allowed domains.\n\n#### `/api/ai` (POST)\nAI chat endpoint using Gemini 2.5 Flash API\n- **Headers**: `Origin: allowed-domain.com` (required)\n- **Request**: `{ clientId: string, content: string }`\n- **Response**: `{ role: string, content: string }`\n\n#### `/api/cleanup` (POST)\nScheduled cleanup job for inactive rooms and messages\n- **Headers**: `x-cron-secret: SERVER_CRON_SECRET` (bypasses origin validation)\n- **Query**: `?dry-run=true` (optional)\n- **Response**: Cleanup summary and statistics\n\n#### `/api/cleanup` (GET)\nHealth check endpoint\n- **Headers**: `Origin: allowed-domain.com` (required)\n- **Response**: Service status and timestamp\n\n### Environment Variables\n\n| Variable | Description | Required | Example |\n|----------|-------------|----------|---------|\n| `NEXT_PUBLIC_FIREBASE_API_KEY` | Firebase API key | ✅ | `AIzaSyC...` |\n| `NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN` | Firebase auth domain | ✅ | `project.firebaseapp.com` |\n| `NEXT_PUBLIC_FIREBASE_PROJECT_ID` | Firebase project ID | ✅ | `my-project` |\n| `NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET` | Firebase storage bucket | ✅ | `project.appspot.com` |\n| `NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID` | Firebase sender ID | ✅ | `123456789` |\n| `NEXT_PUBLIC_FIREBASE_APP_ID` | Firebase app ID | ✅ | `1:123:web:abc` |\n| `NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID` | Firebase measurement ID | ❌ | `G-XXXXXXXXX` |\n| `SERVER_GEMINI_API_KEY` | Gemini AI API key | ✅ | `AIzaSyD...` |\n| `SERVER_CRON_SECRET` | Cron job authentication | ❌ | `secure_random_string` |\n\n## 🚀 Deployment\n\n### Vercel Deployment (Recommended)\n\n1. **Connect Repository**\n   - Import project to [Vercel](https://vercel.com)\n   - Connect your GitHub repository\n\n2. **Configure Environment Variables**\n   - Add all environment variables in Vercel dashboard\n   - Ensure Firebase and Gemini API keys are correctly set\n\n3. **Deploy**\n   - Vercel will automatically build and deploy\n   - Your app will be available at your Vercel domain\n\n### Manual Deployment\n\n```bash\n# Build the application\npnpm build\n\n# Start production server\npnpm start\n```\n\n## 🔒 Security \u0026 Privacy\n\n### Privacy Features\n- **No Authentication Required**: Completely anonymous usage\n- **No Data Persistence**: Messages deleted when rooms close\n- **Client-Side Session Management**: No server-side user tracking\n- **Ephemeral AI Conversations**: AI chat history not permanently stored\n\n### Security Measures\n- **Firebase Security Rules**: Firestore access controls\n- **API Key Protection**: Server-side only API usage\n- **Input Validation**: Sanitized user inputs\n- **Rate Limiting**: Built-in protection against abuse\n- **Origin Validation**: Multi-layered API protection against cross-origin attacks\n\n### API Origin Validation\nThe application implements comprehensive origin-based security for all API endpoints:\n\n#### Multi-Layer Protection\n- **Next.js Middleware**: First-line defense filtering requests before they reach API routes\n- **Route-Level Validation**: Additional validation within each API route handler\n- **Environment Configuration**: Flexible origin management via environment variables\n\n### Production Considerations\n- Update Firebase security rules for production\n- Implement rate limiting for API endpoints\n- Set up monitoring and error tracking\n- Configure proper CORS policies\n- Monitor API security logs for blocked requests\n\n## 🐛 Troubleshooting\n\n### Common Issues\n\n#### Firebase Connection Problems\n```bash\n# Check your Firebase configuration\n- Verify all NEXT_PUBLIC_FIREBASE_* variables are set\n- Ensure Firestore is enabled in Firebase Console\n- Check Firebase project permissions\n```\n\n#### AI Chat Not Working\n```bash\n# Verify Gemini API setup\n- Check SERVER_GEMINI_API_KEY is valid\n- Ensure sufficient API quota/credits\n- Verify AI Mode is enabled in settings\n```\n\n#### Build Errors\n```bash\n# Clear cache and reinstall\nrm -rf .next node_modules pnpm-lock.yaml\npnpm install\npnpm build\n```\n\n#### API Origin Validation Issues\n```bash\n- Verify the origin header is being sent by your client\n- For development, ensure localhost origins are included\n- Check browser console for blocked requests\n\n# Cron jobs failing\n- Verify SERVER_CRON_SECRET is correctly set\n- Ensure cron job sends x-cron-secret header\n- Check API logs for authentication errors\n```\n\n### Debug Mode\nEnable debug logging by adding to your `.env.local`:\n```bash\nNODE_ENV=development\n```\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit changes (`git commit -m 'Add amazing feature'`)\n4. Push to branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- **[Next.js](https://nextjs.org/)** - React framework\n- **[Firebase](https://firebase.google.com/)** - Backend infrastructure\n- **[Gemini AI](https://ai.google.dev/)** - AI API service\n- **[Vercel](https://vercel.com/)** - Deployment platform\n- **[shadcn/ui](https://ui.shadcn.com/)** - UI components\n\n---\n\nBuilt with ❤️ by [Nguyen Mau Minh](https://mewis.me) • [Live Demo](https://chat.mewis.me) • [GitHub](https://github.com/mewisme)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmewisme%2Fprivate-chats","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmewisme%2Fprivate-chats","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmewisme%2Fprivate-chats/lists"}