freepen is a secure chat application built with Next.js and Firebase. It allows users to create private chat rooms protected by passwords and invite others to join these rooms for secure communication. The application prioritizes security and privacy while providing a seamless real-time messaging experience.
- User Authentication: Secure signup and login system with Firebase Authentication
- Create Chat Rooms: Create private rooms with password protection and customizable settings
- Join Chat Rooms: Join existing rooms using room ID and password verification
- Real-time Messaging: Send and receive messages in real-time with instant updates
- Message History: Access complete message history when joining a room
- User Avatars: Unique, consistent avatars for each user in each room using @multiavatar/multiavatar
- End-to-End Encryption: Messages are encrypted on the client side before being sent to the server
- Secure Communication: End-to-end message validation and sanitization
- Rate Limiting: Protection against abuse with configurable rate limits
- Security Logging: Comprehensive logging of security events for monitoring
- Responsive Design: Fully responsive UI that works on desktop, tablet, and mobile devices
- Progressive Web App (PWA): Install as a native app on mobile and desktop devices
- Offline Support: Basic functionality available even without internet connection
- Mobile Optimized: Touch-friendly UI with smooth animations and transitions
- Accessibility: Designed with accessibility in mind for all users
- Next.js 15: React framework with App Router for building the UI
- React 19: Latest version of React with improved performance
- Firebase Authentication: For secure user authentication
- Firestore Database: For storing rooms, messages, and user data
- TailwindCSS 4: For responsive and customizable styling
- React Hook Form: For efficient form handling and validation
- Zod: For robust schema validation and type safety
- TypeScript: For static type checking and improved developer experience
- Iron Session: For secure, encrypted session management
- DOMPurify: For sanitizing user input to prevent XSS attacks
- @multiavatar/multiavatar: For generating unique, consistent SVG avatars
- Jest & Testing Library: For comprehensive testing
- Node.js (v18 or higher)
- npm or yarn
- Firebase account
-
Clone the repository
git clone https://github.com/yourusername/freepen.git cd freepen
-
Install dependencies:
npm install # or yarn install
-
Create a Firebase project at https://console.firebase.google.com/
- Create a new project
- Enable Authentication (Email/Password)
- Create a Firestore Database in production mode
- Generate a new private key for Firebase Admin SDK:
- Go to Project settings > Service accounts
- Click "Generate new private key"
- Save the JSON file securely
- You'll need the
project_id
,client_email
, andprivate_key
values for your .env.local file
-
Update the
.env.local
file with your Firebase configuration:# Firebase Client SDK NEXT_PUBLIC_FIREBASE_API_KEY=your-api-key NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project-id.firebaseapp.com NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project-id.appspot.com NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your-messaging-sender-id NEXT_PUBLIC_FIREBASE_APP_ID=your-app-id NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=your-measurement-id # Session Configuration SESSION_SECRET=your-secure-random-string # Firebase Admin SDK configuration FIREBASE_PROJECT_ID=your-project-id FIREBASE_CLIENT_EMAIL=your-service-account-email@your-project-id.iam.gserviceaccount.com FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYour private key content here...\n-----END PRIVATE KEY-----\n" # Rate Limiting (optional, defaults provided) RATE_LIMIT_ROOM_CREATE=5 RATE_LIMIT_ROOM_JOIN=10 RATE_LIMIT_MESSAGE_SEND=20
-
Run the development server:
npm run dev # or yarn dev
-
Open http://localhost:3000 in your browser
The project includes comprehensive tests to ensure functionality and security:
# Run all tests
npm test
# Run tests in watch mode during development
npm run test:watch
/src/app
: Next.js app router pages and API routes/api
: Backend API endpoints/auth
: Authentication endpoints/messages
: Message handling endpoints/rooms
: Room management endpoints
/room
: Room UI and functionality/login
,/signup
: Authentication UI
/src/components
: Reusable UI components/auth
: Authentication-related components/chat
: Chat-related components/ui
: Generic UI components
/src/contexts
: React contexts for state managementAuthContext
: User authentication stateChatContext
: Chat and messaging state
/src/lib
: Utility functions and service integrationsfirebase.ts
: Firebase client configurationfirebase-admin.ts
: Firebase admin SDK setupdb.ts
: Database utility functionssession.ts
: Session managementrate-limit.ts
: Rate limiting implementationsecurity-logger.ts
: Security event logging
- User authenticates via Firebase Authentication
- Session is established using Iron Session
- User creates or joins a room with password protection
- Room authentication is verified for each request
- Messages are validated, sanitized, and stored in Firestore
- Real-time updates are delivered to all room participants
-
POST /api/auth/session
- Create a new user session
- Body:
{ email: string, password: string }
- Response:
{ success: boolean, user?: User }
-
GET /api/auth/session
- Get current user session
- Response:
{ user?: User }
-
DELETE /api/auth/session
- End current user session
- Response:
{ success: boolean }
-
POST /api/auth/room
- Authenticate to a room with password
- Body:
{ roomId: string, password: string }
- Response:
{ success: boolean, error?: string }
-
GET /api/auth/room
- Check if authenticated to a room
- Query:
?roomId=string
- Response:
{ authenticated: boolean }
-
POST /api/rooms/create
- Create a new chat room
- Body:
{ name: string, password: string }
- Response:
{ success: boolean, roomId?: string, error?: string }
-
POST /api/rooms/join
- Join an existing chat room
- Body:
{ roomId: string, password: string }
- Response:
{ success: boolean, error?: string }
-
GET /api/messages/[roomId]
- Get messages for a room
- Params:
roomId
- Response:
{ messages: Message[] }
-
GET /api/messages/[roomId]/stream
- Stream real-time messages for a room
- Params:
roomId
- Response: Server-sent events with message data
-
POST /api/messages/send
- Send a message to a room
- Body:
{ roomId: string, content: string }
- Response:
{ success: boolean, messageId?: string, error?: string }
For detailed security information, see SECURITY.md. Key features include:
- Password Hashing: Secure hashing for room passwords
- Input Validation: Comprehensive validation with Zod
- Content Sanitization: DOMPurify for XSS prevention
- Rate Limiting: Protection against brute force and DoS attacks
- Session Security: Encrypted cookies with Iron Session
- Content Security Policy: Strict CSP headers
- CORS Configuration: Properly configured CORS policies
- Security Logging: Detailed logging of security events
- Authentication Checks: Thorough authentication on all protected routes
- Firestore Security Rules: Granular access control
The application can be deployed to Vercel:
- Push your code to a GitHub repository
- Connect your repository to Vercel
- Configure environment variables in Vercel
- Add all Firebase configuration variables
- Add SESSION_SECRET and other environment variables
- Deploy the application
- Configure custom domain (optional)
For other deployment options:
- Docker: Dockerfile is provided for containerized deployment
- Firebase Hosting: Can be deployed alongside Firebase services
- Self-hosted: Can be built and served as a static site with API routes
For production, configure these Firestore security rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Allow authenticated users to read and create rooms
match /rooms/{roomId} {
allow read: if request.auth != null;
allow create: if request.auth != null;
}
// Allow room members to read and create messages
match /messages/{messageId} {
allow read: if request.auth != null &&
exists(/databases/$(database)/documents/roomMembers/$(resource.data.roomId + '_' + request.auth.uid));
allow create: if request.auth != null &&
exists(/databases/$(database)/documents/roomMembers/$(request.resource.data.roomId + '_' + request.auth.uid));
}
// Allow users to read and create room memberships
match /roomMembers/{membershipId} {
allow read: if request.auth != null;
allow create: if request.auth != null &&
membershipId.matches(request.resource.data.roomId + '_' + request.auth.uid);
}
// Restrict access to security logs
match /securityLogs/{logId} {
allow read, write: if false; // Only accessible via Firebase Admin SDK
}
}
}
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a new branch (
git checkout -b feature/your-feature-name
) - Make your changes
- Run tests to ensure they pass (
npm test
) - Commit your changes (
git commit -m 'Add some feature'
) - Push to the branch (
git push origin feature/your-feature-name
) - Open a Pull Request
Please ensure your code follows the project's coding standards and includes appropriate tests.
This project is licensed under the MIT License - see the LICENSE file for details.
-
Node.js Version Compatibility
- Issue: Build errors or unexpected behavior
- Solution: Ensure you're using Node.js v18 or higher. Use
nvm
to manage Node.js versions:nvm install 18 nvm use 18
-
Firebase Configuration
- Issue: "Firebase app already exists" error
- Solution: This typically happens in development with hot reloading. Refresh the page to resolve.
-
Environment Variables
- Issue: "Missing environment variables" error
- Solution: Double-check your
.env.local
file contains all required variables listed in the setup section. - Note: Remember that environment variables starting with
NEXT_PUBLIC_
are exposed to the browser.
-
Firestore Permissions
- Issue: "Permission denied" errors when accessing Firestore
- Solution: Verify your Firestore security rules are properly configured and that your Firebase Admin SDK credentials are correct.
-
Build Errors
- Issue: TypeScript errors during build
- Solution: Run
npm run type-check
to identify and fix type issues before building.
-
Vercel Deployment
- Issue: Environment variables not working
- Solution: Ensure all environment variables are properly set in the Vercel project settings.
-
Firebase Admin SDK
- Issue: "Error: Failed to initialize Firebase Admin SDK"
- Solution: Verify that your
FIREBASE_PRIVATE_KEY
is properly formatted with newlines (\n
).
-
Bundle Size Management
- The application uses dynamic imports to reduce initial load time
- Run
npm run analyze
to visualize bundle sizes and identify optimization opportunities
-
Image Optimization
- Use the Next.js Image component for automatic image optimization
- Consider using WebP format for better compression
-
State Management
- Use React Context API for global state that changes infrequently
- Consider using SWR or React Query for data fetching and caching
-
API Route Caching
- Implement appropriate caching headers for API routes
- Use Edge Functions for latency-sensitive operations
-
Database Queries
- Limit query results to reduce data transfer
- Use composite indexes for complex queries
- Implement pagination for large data sets
-
Firestore Best Practices
- Use batch operations for multiple writes
- Implement denormalization for frequently accessed data
- Set up appropriate TTL (Time To Live) for temporary data
The application is tested and supported on the following browsers:
Browser | Minimum Version | Notes |
---|---|---|
Chrome | 90+ | Fully supported |
Firefox | 88+ | Fully supported |
Safari | 14+ | Fully supported |
Edge | 90+ | Fully supported |
Opera | 76+ | Fully supported |
iOS Safari | 14+ | Minor styling differences |
Android Chrome | 90+ | Minor styling differences |
Samsung Internet | 14+ | Minor styling differences |
- The application is designed to meet WCAG 2.1 AA standards
- Screen reader compatible with ARIA attributes
- Keyboard navigation support
- Color contrast ratios meet accessibility standards
- Focus management for modal dialogs and dynamic content
- Implement end-to-end encryption for messages ✓
- Enhance mobile experience with PWA features ✓
- Add file sharing capabilities
- Implement user profiles with avatars ✓
- Add typing indicators and read receipts
- Implement voice and video chat
- Add support for message reactions and threads
- Create a public room directory with discovery features
- Implement advanced search functionality
- Add integration with popular services (Google Drive, Dropbox, etc.)
- Develop a native mobile application
- Implement AI-powered features (smart replies, content moderation)
- Add support for plugins and extensions
- Create an API for third-party integrations
- Implement advanced analytics and insights
freepen is designed as a Progressive Web App, providing a native app-like experience on both mobile and desktop devices.
Users can install freepen as an app on their devices:
- iOS: Open in Safari, tap the Share button, then "Add to Home Screen"
- Android: Open in Chrome, tap the menu button, then "Add to Home Screen" or "Install App"
- Desktop: Open in Chrome, Edge, or other supported browsers, and click the install icon in the address bar
freepen provides basic functionality even when offline:
- Cached Content: Previously loaded chat rooms and messages remain accessible
- Graceful Degradation: Clear offline indicators and fallback UI
- Auto-Reconnect: Automatically reconnects and syncs when connection is restored
The mobile experience is enhanced with:
- Touch-Friendly UI: Larger touch targets and intuitive gestures
- Responsive Animations: Smooth transitions and feedback animations
- Adaptive Layout: UI automatically adjusts to different screen sizes
- Performance Optimizations: Reduced bundle size and optimized rendering for mobile devices
- Service Worker: Custom implementation that manages caching and offline functionality
- Web App Manifest: Defines app appearance and behavior when installed
- Next.js App Router Integration: Uses Next.js built-in PWA support with metadata API
- Offline Page: Dedicated offline experience when network is unavailable
- Lighthouse Score: Optimized for high performance, accessibility, and PWA scores
To work with the PWA features:
- The service worker is implemented in
src/app/service-worker.ts
- Registration happens via
src/app/ServiceWorkerRegistration.tsx
- Build process automatically generates the service worker with
npm run generate-sw
- Test PWA functionality with
npm run test-pwa
Q: Is freepen free to use?
A: Yes, freepen is open-source and free to use under the MIT license.
Q: Can I self-host freepen?
A: Yes, you can deploy freepen to your own infrastructure. Follow the deployment instructions in this README.
Q: Is my data encrypted?
A: Yes! All data is transmitted over HTTPS, and we've implemented end-to-end encryption for messages using the Web Crypto API with AES-GCM 256-bit encryption.
Q: Can I contribute to freepen?
A: Yes! See the Contributing section for details on how to contribute.
Q: How do I report a bug?
A: Open an issue on GitHub with detailed steps to reproduce the bug.
Q: Can I use freepen in my commercial project?
A: Yes, the MIT license allows commercial use.
Q: How do I customize the UI?
A: The UI is built with TailwindCSS, which makes customization straightforward. Modify the tailwind.config.js file to change the theme.
Q: Does freepen support multiple languages?
A: Internationalization is planned but not yet implemented. Contributions for this feature are welcome!
- Next.js - The React framework
- Firebase - Backend services
- TailwindCSS - CSS framework
- All contributors who have helped improve this project