Skip to content

Latest commit

Β 

History

53 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”’ freeChat

freeChat Logo

Zero-Knowledge End-to-End Encrypted Private Messenger
Engineered with Apple iMessage Liquid Glass aesthetics, native W3C Web Cryptography, and real-time WebSockets.

Zero-Knowledge E2EE Cryptography Apple iMessage Glass Tests PWA License


πŸ“‘ Table of Contents


πŸ’‘ Overview

freeChat is an open-source, Zero-Knowledge End-to-End Encrypted (E2EE) messaging platform built to combine uncompromising mathematical privacy with the refined design language of Apple iMessage Liquid Glass.

Unlike traditional web messengers that rely on third-party JavaScript crypto libraries or server-side decryption, freeChat executes all cryptographic operations directly inside the browser using the hardware-accelerated W3C Web Cryptography API (window.crypto.subtle).

πŸ›‘οΈ The Zero-Knowledge Trust Model

  • The Server & Database Are Untrusted: The backend and database only ever receive ciphertext, public keys, and cryptographic initialization vectors (IVs).
  • Zero Plaintext Transmission: Messages, master keys, and private keys never leave the client device unencrypted.
  • Data at Rest Protection: Even in the event of a full server infrastructure compromise or database breach, stored messages cannot be decrypted by an attacker.

✨ Key Features

πŸ” Cryptography & Privacy

  • Hardware-Accelerated Web Crypto: Native browser ECDH (P-256) ephemeral key agreement combined with AES-256-GCM message encryption.
  • Zero-Knowledge Key Derivation: User master keys derived via PBKDF2-HMAC-SHA256 (100,000 iterations) with CSPRNG per-user salts.
  • Anti-Pass-the-Hash Verifiers: Client authentication tokens are hashed server-side with HMAC-SHA256 (v2$) and compared using timing-safe equality checks.
  • In-Memory Key Hardening: Private keys are loaded as non-extractable (extractable: false), preventing memory dumping via cross-site scripting (XSS).
  • Safety Numbers & Fingerprints: Signal/WhatsApp standard 60-digit symmetric safety numbers and 16-character hex fingerprints to detect Man-in-the-Middle (MITM) attacks.

🎨 Apple iMessage Liquid Glass Interface

  • Frosted Glass Panels: Deep blur backdrop filters (backdrop-filter: blur(25px)), translucent floating headers, and multi-layered specular borders.
  • Authentic iMessage Bubbles: Vibrant iOS blue sender bubbles with directional tails, adaptive typography, and smooth spring physics.
  • Dynamic Themes: Seamless light and dark mode with reactive ambient background mesh lighting and iOS status bar tinting.
  • Interactive Feedback: Real-time typing capsule (...), online presence indicators, and animated message delivery states.

⚑ Engineering & Architecture

  • Realtime WebSockets: Low-latency Socket.IO delivery with JWT handshake authentication and room-level authorization checks.
  • Dual-Mode Database Adapter: Instant offline development via the built-in local JSON file store (database/local_db.json), with seamless one-switch migration to Supabase PostgreSQL.
  • Installable PWA: Service-worker caching and web app manifest for a full-screen, standalone app experience on iOS and Android.
  • 100% Free Cloud Stack: Permanently deployable on Render Free Tier (Node.js) paired with Supabase Free Tier (PostgreSQL).

πŸ” Cryptographic Specification

Security Primitives

Component Standard / Algorithm Configuration Security Purpose
Key Agreement ECDH (NIST P-256 / secp256r1) W3C Web Crypto P-256 curve Derives shared 256-bit symmetric secrets between participants without transmitting keys over the wire
Message Cipher AES-256-GCM 256-bit key, 96-bit (12-byte) random IV Authenticated encryption providing confidentiality and integrity for chat payloads
Master Key (KEK) PBKDF2-HMAC-SHA256 100,000 iterations, 16-byte CSPRNG salt Derives the Key Encryption Key used to encrypt and decrypt the user's private key backup
Auth Verifier PBKDF2 + Server HMAC-SHA256 100,000 iterations, :auth domain separation Proves password knowledge to server without sending the raw password or master key
Client Key Vault AES-256-GCM + IndexedDB Session vault key in sessionStorage Encrypts private keys at rest on the client; synced across tabs via BroadcastChannel
Runtime Hardening Non-Extractable CryptoKey extractable: false Prevents JavaScript runtime extraction of raw private key coordinates (d)
Identity Verification SHA-512 Canonical Key Digest 60 decimal digits (12 Γ— 5 blocks) + 16-char hex Symmetrically computed safety number to verify contact keys and defeat MITM attacks

Key Exchange & Message Encryption

  1. Key Agreement: When Alice initiates a chat with Bob, Alice's browser retrieves Bob's public ECDH key. Using Bob's public key and Alice's private key, the browser computes a shared secret:
    Shared Secret K = ECDH(Alice_PrivateKey, Bob_PublicKey)
    
  2. Authenticated Encryption: For every message, a cryptographically secure 12-byte initialization vector (IV) is generated via window.crypto.getRandomValues(). The plaintext is encrypted using AES-256-GCM:
    Ciphertext C, Tag T = AES-256-GCM-Encrypt(K, IV, Plaintext)
    
  3. Transmission: Alice transmits { conversationId, ciphertext: C, iv: IV } through Socket.IO. The server stores and relays only the ciphertext and IV.
  4. Decryption: Bob computes the identical shared secret $K = \text{ECDH}(\text{Bob_PrivateKey}, \text{Alice_PublicKey})$ and decrypts the payload in browser memory.

Non-Extractable In-Memory Keys

When freeChat imports the user's private key into browser memory, it specifies { extractable: false }. The browser's native C++ crypto implementation prohibits any JavaScript code from calling crypto.subtle.exportKey() on that key object. Even in the event of an injected script or malicious extension, the raw private key cannot be exfiltrated from memory.

Safety Numbers & MITM Defense

To ensure that no rogue server or proxy has substituted a contact's public key:

  • Both users' public keys are canonically formatted (sorted coordinates crv, kty, x, y).
  • The keys are sorted lexicographically and hashed with SHA-512.
  • The output is formatted into 12 blocks of 5 decimal digits (60 digits total) matching the Signal / WhatsApp standard.
  • If both parties compare safety numbers and confirm they match, active MITM eavesdropping is mathematically impossible.
  • If a contact's key changes in the database, freeChat revokes the verified checkmark and presents an immediate Security Alert Banner.

πŸ—οΈ System Architecture

flowchart LR
    subgraph ClientA["Client A (Browser / PWA)"]
        UI_A["iMessage UI"] --> WebCrypto_A["Web Crypto API\n(ECDH + AES-256-GCM)"]
        WebCrypto_A --> Vault_A[("IndexedDB Vault\n(AES-GCM Encrypted)")]
    end

    subgraph Infrastructure["freeChat Application Server (Untrusted)"]
        Server["Node.js / Express Gateway\n& Socket.IO Realtime"]
        DBAdapter{"Universal DB Adapter"}
        LocalStore[("Local JSON File\ndatabase/local_db.json")]
        CloudStore[("Supabase Cloud\nPostgreSQL")]
        
        Server --> DBAdapter
        DBAdapter -->|Offline / Default| LocalStore
        DBAdapter -->|Configured| CloudStore
    end

    subgraph ClientB["Client B (Browser / PWA)"]
        WebCrypto_B["Web Crypto API\n(ECDH + AES-256-GCM)"] --> UI_B["iMessage UI"]
        WebCrypto_B --> Vault_B[("IndexedDB Vault\n(AES-GCM Encrypted)")]
    end

    WebCrypto_A == "Ciphertext + IV (E2EE)" ==> Server
    Server == "Ciphertext + IV (E2EE)" ==> WebCrypto_B
Loading

πŸ“ Project Directory Structure

freeChat/
β”œβ”€β”€ database/
β”‚   β”œβ”€β”€ schema.sql            # PostgreSQL production schema & RLS policies
β”‚   └── local_db.json         # Local JSON store (auto-generated for offline mode)
β”œβ”€β”€ public/                   # Frontend SPA client
β”‚   β”œβ”€β”€ css/
β”‚   β”‚   β”œβ”€β”€ variables.css     # Design tokens, color palette, spring curves
β”‚   β”‚   β”œβ”€β”€ glass.css         # Glassmorphism, backdrop blurs, modal surfaces
β”‚   β”‚   β”œβ”€β”€ imessage.css      # Apple iMessage chat bubbles, tails, typing pills
β”‚   β”‚   └── main.css          # Layouts, responsive breakpoints, resets
β”‚   β”œβ”€β”€ js/
β”‚   β”‚   β”œβ”€β”€ api.js            # Authenticated REST API wrapper
β”‚   β”‚   β”œβ”€β”€ app.js            # Application state machine & DOM orchestrator
β”‚   β”‚   β”œβ”€β”€ crypto.js         # Web Crypto E2EE engine, vault store, safety numbers
β”‚   β”‚   β”œβ”€β”€ socket.js         # Socket.IO connection manager & event dispatcher
β”‚   β”‚   └── ui.js             # UI rendering, toasts, and DOM sanitation
β”‚   β”œβ”€β”€ favicon.svg           # Application lock emblem
β”‚   β”œβ”€β”€ index.html            # Main Single Page Application shell
β”‚   β”œβ”€β”€ manifest.json         # Progressive Web App manifest
β”‚   └── sw.js                 # Service worker for offline shell caching
β”œβ”€β”€ server/                   # Backend application server
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   └── db.js             # Universal DB adapter (Supabase PostgreSQL / Local JSON)
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   └── auth.js           # JWT verification, security headers, rate limiting
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ auth.js           # Registration, pre-login, login, user profile
β”‚   β”‚   └── chat.js           # Search, conversation management, message history
β”‚   └── server.js             # Express app entry, HTTP server, Socket.IO router
β”œβ”€β”€ test/
β”‚   └── verify.js             # Automated 15-suite verification & security test runner
β”œβ”€β”€ .env.example              # Environment variables template
β”œβ”€β”€ package.json              # Project dependencies & npm scripts
└── README.md                 # Technical architecture manual

πŸš€ Getting Started

Prerequisites

  • Node.js >= 18.0.0 (supports native Web Crypto and ES modules)
  • npm >= 8.0.0

Installation & Local Run

  1. Clone the repository:

    git clone https://github.com/your-username/freeChat.git
    cd freeChat
  2. Install dependencies:

    npm install
  3. Start the application:

    npm start

    For auto-reloading development mode:

    npm run dev
  4. Open http://localhost:3000 in your browser.

πŸ’‘ Immediate Offline Evaluation: freeChat initializes its built-in local JSON database (database/local_db.json) automatically when no external database is configured. You can start chatting and testing immediately without creating accounts or setting up cloud services.


βš™οΈ Configuration & Environment

To configure production secrets or cloud persistence, create a .env file in the project root:

cp .env.example .env
Variable Required Default Value Description
PORT Optional 3000 HTTP and WebSocket listening port
JWT_SECRET Recommended Built-in dev key Secret for signing session tokens (must be a strong 64-character key in production)
SUPABASE_URL Optional Empty (Local mode) Full Supabase project URL (https://your-project-id.supabase.co)
SUPABASE_KEY Optional Empty (Local mode) Supabase service_role secret API key (required for server-side RLS operations)
ALLOWED_ORIGINS Optional Auto / Empty Comma-separated CORS whitelist (leave empty for automatic same-origin and cloud detection)
NODE_ENV Optional development Environment mode (development or production)

πŸ—„οΈ Database Persistence Options

1. Zero-Config Local Mode (Default)

When SUPABASE_URL is omitted, the universal database adapter (server/config/db.js) uses local file storage:

  • Stores records in database/local_db.json.
  • Implements concurrency-safe atomic file writes with .tmp staging and fs.renameSync.
  • Automatically generates timestamped recovery backups if malformed JSON is encountered.

2. Supabase PostgreSQL Cloud Setup

For scalable, multi-device cloud storage:

  1. Create a project at Supabase.com.
  2. In the Supabase Dashboard, open the SQL Editor and run the contents of database/schema.sql.
  3. Copy your Project URL and service_role secret key from Project Settings $\rightarrow$ API.
  4. Update your .env file:
    SUPABASE_URL=https://your-project-id.supabase.co
    SUPABASE_KEY=your-supabase-service-role-secret-key
  5. Restart the server (npm start). freeChat will automatically connect to Supabase PostgreSQL.

πŸ“‘ API & Realtime Reference

REST Endpoints

Method Endpoint Auth Description
POST /api/auth/register Public Registers a new account with encrypted key backup and auth verifier
POST /api/auth/pre-login Public Returns key derivation salt (anti-enumeration protected)
POST /api/auth/login Public Validates zero-knowledge auth verifier and issues session JWT
GET /api/auth/me Bearer Validates active session token and returns user profile
GET /api/auth/user/:username Bearer Returns public identity and public key for a contact
GET /api/chat/users/search?q= Bearer Searches registered users by username
GET /api/chat/conversations Bearer Lists all active conversations for the authenticated user
POST /api/chat/conversations/direct Bearer Initializes or retrieves a 1-on-1 direct conversation
GET /api/chat/conversations/:id/messages Bearer Retrieves encrypted message history (enforces participant membership)
GET /api/health Public System liveness probe and active database engine indicator

Socket.IO Realtime Events

Event Name Direction Description
connection Client $\rightarrow$ Server Authenticates connection using handshake token (auth: { token })
online_users_list Server $\rightarrow$ Client Transmits array of currently active user IDs upon connect
user_status_change Server $\rightarrow$ Client Broadcasts real-time online/offline presence changes
join_conversation Client $\rightarrow$ Server Joins conversation room conv:id (server validates participant membership)
typing_start / typing_stop Client $\rightarrow$ Server Emits typing state; throttled server-side to prevent room flooding
user_typing Server $\rightarrow$ Client Relays typing indicator capsule to conversation participants
send_message Client $\rightarrow$ Server Sends encrypted payload; server enforces sender ID from JWT token
new_message Server $\rightarrow$ Client Dispatches ciphertext and IV to all conversation participants
conversation_updated Server $\rightarrow$ Client Notifies recipient's personal room (user:id) to refresh sidebar snippet

πŸ›‘οΈ Threat Model & Security Matrix

Attack Vector Threat Scenario freeChat Defense & Mitigation
Compromised Database Attacker obtains full read access to database storage Mathematically Protected. Database contains only AES-256-GCM ciphertext, public keys, and encrypted private key backups. No unencrypted messages, master keys, or passwords ever touch disk.
Malicious / Rogue Server Server attempts to substitute Bob's public key (MITM) Detected by Safety Numbers. Symmetrically derived 60-digit safety numbers will mismatch. Stored contact records trigger an immediate visual key-change warning banner.
Network Eavesdropping Attacker intercepts traffic on unencrypted Wi-Fi Transport + Payload Encryption. HTTPS/WSS encrypts transit; Web Crypto AES-256-GCM ensures message payloads remain unbreakable ciphertext even if TLS terminates at an intermediate proxy.
DOM Injection / XSS Malicious script attempts to steal in-memory keys Non-Extractable Keys. In-memory private keys are marked extractable: false. The browser's native crypto implementation refuses to export raw key coordinates.
Username Enumeration Attacker scans /pre-login to harvest active accounts Anti-Enumeration Defense. The endpoint computes and returns a deterministic pseudorandom salt for non-existent users with identical HTTP status (200 OK) and latency.
Replay / Pass-the-Hash Attacker captures auth verifier to impersonate user Server HMAC Protection. Auth verifiers are hashed server-side with HMAC-SHA256 (v2$). The stored database hash cannot be replayed as a client login token.

πŸ§ͺ Automated Verification Suite

freeChat includes an end-to-end automated verification suite covering cryptography, authorization boundaries, concurrency, and network security.

Run the test suite:

npm test

Coverage (15 Verified Suites)

  • Web Crypto Engine: Complete ECDH P-256 key agreement & AES-256-GCM encryption roundtrip.
  • Zero-Knowledge Key Backup: PBKDF2 derivation, client-side encryption, and cross-device recovery.
  • Database & Schema: User/conversation CRUD operations, participant indexing, and message persistence.
  • Username Validation: Strict character whitelisting (3–30 chars: lowercase, numbers, _, -, .).
  • IDOR / BOLA Defense: Strict object-level authorization blocking non-participant conversation access.
  • Socket Security: Handshake authentication, room access verification, and sender identity spoofing prevention.
  • Anti-Enumeration: Pre-login deterministic pseudorandom salts and zero unauthenticated key exposure.
  • Auth Verifier Hardening: PBKDF2 (:auth) derivation, server HMAC hashing, and timing-safe equality.
  • Safety Numbers & MITM Defense: Symmetric 60-digit number computation and key-substitution alerting.
  • Vault Security: Encrypted client storage at rest and non-extractable in-memory keys (extractable: false).
  • HTTP Security Headers: Strict Content Security Policy (CSP), HSTS, and X-Frame-Options clickjacking protection.
  • Rate Limiting: Brute-force throttling on authentication endpoints and IP anti-spoofing verification.
  • PostgreSQL RLS: Verification of Row Level Security policies for multi-tenant database isolation.
  • Atomic Local Storage: Concurrency-safe atomic writes and automated corruption backup preservation.
  • Deep Hardening: Strict registration schema validation and real-time typing flood throttling.

πŸ“² Mobile Installation (PWA)

freeChat functions as a standalone Progressive Web App with zero third-party app store requirements:

  • iOS (Safari): Open the URL $\rightarrow$ tap Share $\rightarrow$ tap Add to Home Screen $\rightarrow$ tap Add.
  • Android (Chrome): Open the URL $\rightarrow$ tap the menu ($\vdots$) $\rightarrow$ tap Install App / Add to Home Screen.

When launched from the home screen, freeChat runs full-screen with native iOS safe-area adaptation, status bar tinting, and no browser chrome.


🌐 Production Deployment

Option A: 1-Click Render.com Blueprint (Recommended)

freeChat includes a pre-configured render.yaml infrastructure specification:

  1. Push your repository to GitHub:
    git add .
    git commit -m "Production-ready freeChat"
    git push origin main
  2. Log in to Render.com and navigate to Blueprints $\rightarrow$ New Blueprint Instance.
  3. Select your repository. Render automatically reads render.yaml, configures the Node service, sets up zero-downtime healthchecks (/api/health), and generates a cryptographically secure JWT_SECRET.
  4. Enter your SUPABASE_URL and SUPABASE_KEY (service_role key), then click Apply.

Option B: Manual Cloud Setup (Render, Railway, Fly.io, Heroku)

  1. Connect your GitHub repository to your cloud platform.
  2. Configure build & start commands:
    • Build Command: npm install
    • Start Command: npm start
    • Healthcheck Path: /api/health
  3. Set the following Environment Variables:
    • NODE_ENV: production
    • TRUST_PROXY: true
    • JWT_SECRET: (A random 64-character string)
    • SUPABASE_URL: (Your Supabase project URL, e.g. https://xyz.supabase.co)
    • SUPABASE_KEY: (IMPORTANT: Your Supabase service_role key to operate with RLS)
    • ALLOWED_ORIGINS: (Your custom domain, e.g. https://mychat.com)

Option C: Docker Container Deployment

freeChat includes an optimized, non-root Alpine container:

# 1. Build the Docker image
docker build -t freechat .

# 2. Run the container
docker run -d \
  --name freechat \
  -p 3000:3000 \
  -e NODE_ENV=production \
  -e JWT_SECRET="your-strong-random-secret-key-at-least-32-chars" \
  -e SUPABASE_URL="https://your-project.supabase.co" \
  -e SUPABASE_KEY="your-supabase-service-role-secret-key" \
  freechat

Verify container health:

docker inspect --format='{{json .State.Health.Status}}' freechat

πŸ“„ License

This project is open-source and licensed under the MIT License.


Built with ❀️ for privacy, freedom of speech, and craftsmanship.

About

Zero-Knowledge End-to-End Encrypted (E2EE) private messenger featuring Apple iMessage Liquid Glass aesthetics. Built with native W3C Web Crypto (ECDH P-256 + AES-256-GCM), real-time WebSockets, non-extractable keys, MITM safety numbers, and installable PWA support. Powered by Node.js with dual-mode zero-config local storage and Supabase PostgreSQL.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages