Repository navigation
Home
RacoonByte01 edited this page Oct 7, 2026
·
2 revisions
A lightweight, self-hosted API for sending and receiving PGP-encrypted messages, with built-in user, role, and group management. Run it on your own server and keep full control over your data.
| Component | Version |
|---|---|
| Java | 17 |
| Spring Boot | 4.1.1 |
| Maven | 3.9.16 |
| Storage | Flat JSON files (data/) |
| License | GPL-3.0 |
- User management (create, update, delete, login with tokens)
- Group management (create, join, leave, rename, delete)
- Per-group role management with a 7-bit permission mask
- Send and receive PGP-encrypted messages per group
git clone https://github.com/RacoonByte01/ChatyChat.git
cd ChatyChat
./mvnw spring-boot:runOr build a runnable jar:
./mvnw clean package
java -jar target/chatychat-0.0.1-SNAPSHOT.jarThe server listens on http://localhost:8080 (default Spring Boot port).
Tip
Create a user, log in to get a token, then send that token on every request.
Parameters travel as multipart form fields (curl -F):
curl -F 'name=alice' -F 'password=secret' "http://localhost:8080/user"
TOKEN=$(curl -s -F 'name=alice' -F 'password=secret' "http://localhost:8080/login")
curl -s -H "Authorization: $TOKEN" "http://localhost:8080/groups"Send PGP-encrypted messages straight from a gpg pipe:
gpg -ear <id-pgp> message.txt | curl -H "Authorization: $TOKEN" -F 'message=<-' "http://localhost:8080/send/0"Full details with one curl per endpoint: API Reference.
- Architecture — components, data flow, authentication sequence
-
API Reference — all endpoints, parameters,
curlexamples - Roles — the 7-bit permission model
- Messages are only stored if the content contains a PGP armor marker (
-----BEGIN PGP MESSAGE-----, etc.). Anything else is silently discarded — the server never encrypts, it only stores blocks you already encrypted client-side. - Persistence is flat JSON files under
data/; there is no database and no concurrent-write protection. - Tokens never expire; delete them explicitly (
/logout,/token). -
POST /loginwith a wrong password returns the stringainstead of an error. -
GET /user/{name}returnsnull(empty body) when the user does not exist. - No rate limiting, no HTTPS termination — put it behind a reverse proxy for production.