Skip to content

danarrib/cinderbox-chat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cinderbox Chat

A privacy-focused ephemeral messaging platform built for self-hosting. No accounts, no phone numbers, no logs — just encrypted rooms that disappear.

Cinderbox Chat was designed from the ground up to run on infrastructure you control. It deploys on any standard PHP/MySQL shared host with no build step, no Node.js, no Docker, and no CDN.

Desktop Mobile
image image

Live Demo

A public instance is available at cc.outros.net — free to use for testing and real conversations. No registration required.


Features

Messaging

  • Text, image, and audio messages — send text, photos, and voice clips up to 2 minutes
  • Message replies — reply to any specific message; a quoted snippet appears inline and clicking it scrolls to the original
  • Single-view messages — content that can only be opened once; the recipient must be online to open it, and it is permanently wiped from their device after viewing
  • Message deletion — delete a message for yourself only, or request deletion from all recipients' devices and track confirmation per recipient

Rooms

  • No accounts — identify yourself with a handle and a password, nothing more
  • Ephemeral rooms — choose a retention period (1h, 6h, 12h, 24h) or create a permanent room; ephemeral rooms and all their messages are automatically purged
  • Custom room names and avatars — names stay on your device only, never stored on the server
  • Multiple rooms — manage several conversations simultaneously from a single interface

Privacy & Security

  • End-to-end encryption — all message content is encrypted in the browser before it leaves your device, using AES-256-GCM with keys derived via PBKDF2 (200,000 iterations, SHA-256)
  • Zero plaintext on the server — the server stores only ciphertext blobs it cannot read
  • No identity correlation — your identity tag is SHA-256(handle + room_id), making it impossible to correlate your presence across different rooms
  • Password never leaves the browser — the room password is used locally to derive the encryption key and is never transmitted
  • Single-view offline protection — opening a single-view message requires a confirmed server sync first; disabling your network connection before tapping will result in a failure, not content exposure
  • Crash-recovery for single-view — if the app is force-killed mid-open, a sentinel flag ensures the deletion acknowledgement is sent on the next launch
  • Message deletion tracking — "Delete for everyone" sends a signed deletion request to each recipient and tracks confirmation; the sender retains a tombstone to audit who confirmed

UI

  • Dark and light themes — persisted per device
  • Internationalisation — English and Brazilian Portuguese (pt-BR); language selector in the nav bar
  • 5-state delivery ticks — 🕐 queued → ✓ server received → ✓✓ downloaded → ✓✓ (partial) viewed → ✓✓ all viewed
  • Message Info modal — tap any outgoing message to see per-recipient delivery, view, and deletion status
  • Context menu — right-click or long-press any message to reply, delete, or view message data
  • Image compression — photos are automatically resized to 1000px and re-encoded as AVIF (with WebP/JPEG fallback) before sending
  • Single-view toggle in image preview — the single-view toggle is available directly inside the image preview modal, so it can be set after selecting the image
  • No CDN, no external requests — the entire frontend is a single self-contained HTML file

Self-Hosting

Cinderbox Chat deploys as a small set of static files alongside a single PHP script. There is no build step, no package manager, and no environment variables.

File Role
index.html Full SPA frontend — all UI and client-side logic
api.php Backend API — all database interactions
sw.js Service Worker — offline shell and PWA update cycle
manifest.json PWA manifest — enables "Add to Home Screen"
icon.svg Application icon
.htaccess HTTP→HTTPS redirect and HSTS header (Apache)

index.html and api.php are the only files strictly required for the app to function. The remaining three enable PWA installation and the offline fallback shell.

Requirements

  • PHP 8.0+ with PDO and PDO_MySQL
  • MySQL 8.0+ (or MariaDB equivalent)
  • Any standard web host (shared hosting works fine)

Setup

  1. Copy the files to your web root:

    scp src/api.php src/index.html src/sw.js src/manifest.json src/icon.svg src/.htaccess user@yourhost.com:~/public_html/
  2. Visit your site in a browser. A setup screen will appear asking for your MySQL credentials.

  3. Submit the form. config.php is written automatically and the database schema is created. The setup endpoint is permanently disabled after first run.

That's all. No build step, no package manager, no environment variables.

Deploying Updates

scp src/api.php src/index.html src/sw.js src/manifest.json src/icon.svg src/.htaccess user@yourhost.com:~/public_html/

Any new database migrations run automatically on the first request after deployment.

Important — bump the Service Worker version on every deploy that changes index.html. Open sw.js and increment the cache name (e.g. cinderbox-v4cinderbox-v5) before uploading. This triggers an automatic update cycle: the new SW activates immediately and all open tabs reload with the fresh version. Without this step, users on Android/iOS PWA may continue running the old version indefinitely.


Automated Testing

The test suite uses Playwright and runs against a live instance of the app. Each test produces a self-contained evidence report with screenshots and step-by-step descriptions.

Prerequisites

Node.js is required. Install dependencies once:

npm install
npx playwright install chromium

Running Tests

npm test                                         # run all tests against cc.outros.net
BASE_URL=https://your-instance.com npm test      # run against a different instance
npm run test:headed                              # run with a visible browser window

Test Evidence

Each passing test generates a directory under docs/testing_evidences/ containing a README.md report and one screenshot per step. These reports are committed to the repository as verifiable records of tested behaviour — only after all tests pass.

All evidence reports live under docs/testing_evidences/.

Document Description
Test 001 — Solo Full Workflow End-to-end solo session: create room, send text and image, set profile, toggle theme and language, rename and delete room
Test 002 — Two Participants Workflow Two-browser session: join notification, text exchange, single-view message, leave room, delete room
Test 003 — Audio Message Workflow Two-browser session: record and send audio, receive audio player, room deletion detected by participant
Test 004 — Single-View Image Message Two-browser session: send single-view image, open and wipe on recipient side, deletion ack confirmed
Test 005 — Message Deletion Two-browser session: delete for everyone, tombstone on sender, message removed on recipient
Test 006 — Message Reply Two-browser session: reply via context menu, quoted snippet rendered inline on recipient
Test 007 — Multiple Rooms Single-browser session: create two rooms, verify message isolation, switch between rooms
Test 008 — Room Retention Policy Single-browser session: create rooms with 1h, permanent, and 12h retention, verify settings panel
Test 009 — Join with Wrong Password Two-browser session: client-side key validation failure, error shown, join screen remains
Test 010 — Profile Propagation Two-browser session: profile_update broadcast, handle visible in participant list on recipient
Test 011 — Clear Data Single-browser session: send message, clear all device data, verify landing screen and clean localStorage

Security Design

Property Implementation
Encryption algorithm AES-256-GCM
Key derivation PBKDF2, SHA-256, 200,000 iterations
Key material Room password (never transmitted)
Identity tag SHA-256(handle + room_id) — per-room, non-correlatable
Server knowledge Ciphertext only — no plaintext, no metadata, no IP logs
SQL injection PDO prepared statements throughout, no exceptions
Delete tokens Stored as SHA-256 hash, verified with hash_equals
Error disclosure error_reporting(0) — no stack traces or error output
Rate limiting 60 messages per sender tag per minute
Message size 2 MB hard limit enforced server-side
Setup endpoint Disabled permanently after first run (returns 403)
Config file Excluded from git via .gitignore
XSS — received content Avatars validated to data:image/ prefix; all user-controlled values HTML-escaped before DOM insertion

Documentation

Document Description
User Manual End-user guide: rooms, messaging, single-view, profiles, notifications
Self-Hosting Guide Deployment, database setup, Service Worker versioning, reverse proxy config
Architecture Sync model, storage layers, message flow, presence model, ACK system
Encryption Cryptographic primitives, key derivation, threat model
Client Database IndexedDB schema, localStorage keys, outbox structure
Server Cleanup Server-side expiry routines: lazy expiry, global expiry, inbox delivery

License

See LICENSE.

About

Privacy-focused ephemeral messaging platform. No accounts, no logs, no plaintext on the server. All encryption is client-side (Web Crypto API). Deployable on standard shared PHP/MySQL hosting.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors