A social media platform built with Rust, designed as a learning project exploring backend development, graph databases, E2E encryption, and real-time communication.
- Backend: Rust with Axum, SQLx, Argon2id, JWT
- Frontend: SvelteKit 5, TypeScript, Tailwind CSS
- Database: PostgreSQL 16
- E2E Encryption: Signal Protocol (X3DH + Double Ratchet) via
@privacyresearch/libsignal-protocol-typescript - Post Signing: Ed25519 signatures via Web Crypto API
- Planned: Neo4j (graph queries), Redis (caching/pub-sub), MinIO (media storage)
-
Start PostgreSQL:
docker compose up -d
-
Configure environment:
cp backend/.env.example backend/.env # Edit backend/.env and set a strong JWT_SECRET -
Run the backend:
cd backend cargo runThe API will be available at
http://localhost:3000. -
Run the smoke test:
./test.sh
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/health |
Health check |
| POST | /api/v1/auth/register |
Register a new user |
| POST | /api/v1/auth/login |
Log in |
| GET | /api/v1/users/:id |
Get user by ID |
| PUT | /api/v1/profile |
Update your profile |
| POST | /api/v1/users/:id/follow |
Follow a user |
| DELETE | /api/v1/users/:id/follow |
Unfollow a user |
| POST | /api/v1/posts |
Create a post (with optional Ed25519 signature) |
| GET | /api/v1/posts/:id |
Get a post |
| DELETE | /api/v1/posts/:id |
Delete your post |
| POST | /api/v1/posts/:id/react |
React to a post (any emoji) |
| DELETE | /api/v1/posts/:id/react |
Remove reaction |
| GET | /api/v1/posts/:id/reactions |
Get reactions for a post |
| GET | /api/v1/posts/:id/replies |
Get replies to a post |
| GET | /api/v1/feed |
Get your feed |
| POST | /api/v1/chats |
Create a conversation |
| GET | /api/v1/chats |
List conversations |
| GET | /api/v1/chats/:id/messages |
Get messages (encrypted) |
| GET | /api/v1/chats/:id/members |
List conversation member IDs |
| PUT | /api/v1/keys/bundle |
Upload Signal Protocol key bundle |
| GET | /api/v1/keys/bundle/:user_id |
Fetch key bundle (pops one OPK) |
| GET | /api/v1/keys/count |
Get remaining OPK count |
| POST | /api/v1/upload |
Upload an image |
| GET | /api/v1/uploads/:filename |
Serve uploaded image |
| WS | /api/v1/ws |
WebSocket (real-time encrypted chat) |
See docs/architecture.md for full architecture and API design.
oceana/
├── backend/
│ ├── Dockerfile # Multi-stage Rust build (rust:alpine → alpine)
│ ├── src/
│ │ ├── main.rs # Entry point, server startup, migrations
│ │ ├── auth.rs # JWT, Argon2id, AuthUser extractor
│ │ ├── chat.rs # WebSocket connection manager
│ │ ├── error.rs # Error types → JSON responses
│ │ ├── models.rs # DB models, request/response structs, Signal types
│ │ └── routes.rs # Route handlers (REST + WebSocket + Signal keys)
│ └── migrations/
│ ├── 001_initial.sql # users, posts, follows
│ ├── 002_chat.sql # conversations, messages
│ ├── 003_attachments.sql # image support
│ ├── 004_bot_flag.sql # bot/human distinction
│ ├── 005_reactions.sql # emoji reactions
│ ├── 006_emoji_reactions.sql
│ ├── 007_signal_keys.sql # Signal Protocol keys, prekeys, post signatures
│ └── 999_seed.sql # test data
├── frontend/
│ ├── Dockerfile # Node 22 alpine, Vite dev server
│ ├── src/
│ │ ├── lib/
│ │ │ ├── api.ts # Typed fetch wrapper with JWT + 401 auto-logout
│ │ │ ├── types.ts # TS interfaces mirroring Rust models
│ │ │ ├── ws.ts # WebSocket connection manager
│ │ │ ├── crypto/ # Signal Protocol E2EE module
│ │ │ │ ├── index.ts # Singleton init, key generation on first use
│ │ │ │ ├── store.ts # IndexedDB-backed Signal Protocol store (TOFU)
│ │ │ │ ├── keys.ts # Key generation, bundle upload, OPK replenishment
│ │ │ │ └── signal.ts # X3DH session init, encrypt/decrypt, Ed25519 signing
│ │ │ ├── stores/
│ │ │ │ ├── auth.ts # Auth store (localStorage, SSR-safe)
│ │ │ │ └── chat.ts # Chat store with E2EE decrypt/encrypt
│ │ │ └── components/
│ │ │ └── Markdown.svelte
│ │ └── routes/
│ │ ├── +layout.svelte
│ │ ├── +page.svelte # Feed with signed posts + verification badges
│ │ ├── chat/
│ │ │ ├── +page.svelte # Conversation list
│ │ │ └── [id]/+page.svelte # E2E encrypted chat
│ │ ├── login/+page.svelte
│ │ ├── register/+page.svelte
│ │ ├── settings/+page.svelte
│ │ ├── users/[id]/+page.svelte
│ │ └── posts/[id]/+page.svelte
├── docs/
│ ├── architecture.md
│ ├── dev-pilot.md
│ └── lessons.md
├── docker-compose.yml # postgres + backend + frontend
└── .gitignore
This is a personal learning project.