Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
56b2fb2
docs: added CLAUDE.md
CarlosLugones Mar 4, 2026
1012f01
fix: upgraded Elysia to v1.4.18 to fix security issue CVE-2025-66457
CarlosLugones Mar 4, 2026
564830e
docs: updated README.md
CarlosLugones Mar 4, 2026
f154920
perf: included ImageMessage in the Message union type
CarlosLugones Mar 4, 2026
e5c1ed2
fix: only broadcast list of users when the room still has members
CarlosLugones Mar 4, 2026
a880912
perf: removed redundant usernames ephemeral storage since it can be d…
CarlosLugones Mar 4, 2026
fef5178
feat: validate room IDs and usernames
CarlosLugones Mar 4, 2026
5a4243f
feat: added max payload size, improved port handling
CarlosLugones Mar 4, 2026
ab23441
perf: improved logger with hierarchy
CarlosLugones Mar 4, 2026
816a370
fix: use public elysia/ws import, pin bun-types, set moduleResolution…
CarlosLugones Mar 4, 2026
41b1afa
feat: check if the client is a room member before allowing broadcast …
CarlosLugones Mar 4, 2026
a523847
perf: username made optional for system-level error messages
CarlosLugones Mar 4, 2026
96cd19f
fix: added missing type to the UserListMessage interface
CarlosLugones Mar 4, 2026
92c2c86
perf: improved error handling when joining room
CarlosLugones Mar 4, 2026
e32935e
fix: replaced require() with ESM import and update tsconfig for bundl…
CarlosLugones Mar 4, 2026
7aaf8e6
tests: added basic unit tests
CarlosLugones Mar 4, 2026
e84393c
chore: added GitHub action to run unit tests on pull request and push
CarlosLugones Mar 4, 2026
e8828bb
docs: updated CLAUDE.md
CarlosLugones Mar 4, 2026
c92ed7a
repo: upgraded version to 1.2.1
CarlosLugones Mar 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Test

on:
pull_request:
push:
branches:
- main
- develop

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install
- run: bun test
54 changes: 54 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

```bash
bun install # Install dependencies
bun run dev # Start dev server with hot reload (watches src/index.ts)
bun test # Run unit tests
```

**Docker:**
```bash
docker-compose up # Run production server on port 8000
```

## Environment Variables

| Variable | Default | Description |
|---|---|---|
| `PORT` | `8000` | Server port |
| `NODE_ENV` | (dev if unset) | Set to `production` to disable all logging |
| `LOG_LEVEL` | `all` | One of: `all`, `debug`, `info`, `warn`, `error` |
| `MAX_PAYLOAD_SIZE_MB` | `10` | Maximum WebSocket message size in MB |

## Architecture

Single-file entry point at `src/index.ts` bootstraps an **Elysia** (Bun-native) HTTP/WebSocket server. All real-time communication happens over the `/ws` WebSocket endpoint.

**Data flow:**
1. Client connects via WebSocket at `/ws`
2. Client sends JSON messages typed by `MessageType` enum (`src/types.ts`)
3. `index.ts` dispatches on `message.type` to `ChatManager` methods
4. `ChatManager` (`src/chat-manager.ts`) manages in-memory room state and broadcasts back to all room members

**Key design decisions:**
- **Zero persistence**: All state lives in `ChatManager.rooms` (a `Map<string, RoomData>`). Rooms are created on first join and deleted when empty. No database, no disk writes.
- **No authentication**: Username uniqueness is enforced per-room only; duplicate usernames in the same room are rejected.
- **Logging suppressed in production**: `Logger` (`src/utils/logger.ts`) silently drops all log calls when `NODE_ENV=production`.

**Source layout:**
- `src/index.ts` — Elysia app, WebSocket handlers, HTTP routes (`/`, `/health`)
- `src/chat-manager.ts` — `ChatManager` class: `joinRoom`, `leaveRoom`, `isInRoom`, `broadcastMessage`, `sendError`, `handleDisconnect`
- `src/types.ts` — All message interfaces and `MessageType` enum
- `src/config.ts` — Reads env vars into a typed `config` object
- `src/utils/logger.ts` — Leveled logger, no-ops in production
- `src/templates/index.html.ts` — HTML landing page rendered for browser visits to `/`

**WebSocket message types** (all exchanged as JSON):
- `JOIN_ROOM` / `LEAVE_ROOM` — client-initiated room membership
- `CHAT_MESSAGE` / `IMAGE_MESSAGE` — relayed to all room members (images as base64)
- `USER_LIST` — server-broadcast after membership changes
- `ERROR` — server-sent to individual client on failure
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ This server works standalone. You can use this frontend client [here](https://gi
## Privacy Highlights

- **No Message Storage**: Messages are not stored on the server, only relayed between authorized participants
- **No Logs**: All logs are disabled in production mode
- **No Logs**: All logs are disabled when `NODE_ENV=production`. Logs are active in development mode.
- **No Third-Party Services**: Operates independently without external service dependencies
- **Encrypted Trnamission**: All messages are encrypted in transit using secure WebSockets
- **Encrypted Transmission**: Messages are transmitted over WSS (WebSocket Secure). TLS termination is handled at the infrastructure level (e.g. reverse proxy). The server itself does not manage certificates.
- **Open Source**: Full transparency about how your data is handled

## Getting Started
Expand Down
Binary file modified bun.lockb
Binary file not shown.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"name": "private-chat-server",
"version": "1.2.0",
"version": "1.2.1",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"test": "bun test",
"dev": "bun run --watch src/index.ts"
},
"dependencies": {
"elysia": "latest"
"elysia": "^1.4.27"
},
"devDependencies": {
"bun-types": "latest"
"bun-types": "1.2.4"
},
"module": "src/index.js"
}
Loading