🔍 Panoramica Sistema
ShutAppChat è una piattaforma di messaggistica con architettura client-server moderna e focus sulla privacy.
Componenti Principali
- Client App (Kotlin Android): Applicazione nativa Android (Min SDK 24, Target SDK 34) con architettura MVVM
- REST API (PHP 8+): Gestione autenticazione JWT, contatti, profili e upload media
- WebSocket Server (Go 1.21+): Server real-time per messaggi istantanei con goroutine-based messaging
- Database (MariaDB 10.5+): Storage persistente con Room Database locale sul client
🔐 Caratteristiche Privacy
- ✓ Messaggi NON salvati: I messaggi vanno direttamente da client a client via WebSocket, NON vengono persistiti sul server
- ✓ TLS Security: Comunicazioni protette con TLS 1.2+ (HTTPS/WSS)
- ✓ JWT Authentication: Token HS256 con scadenza 7 giorni
- ✓ Metadata Minimization: Solo dati essenziali salvati (utenti, gruppi, contatti)
- ✓ Temporary Storage: Messaggi non consegnati (destinatario offline) mantenuti temporaneamente, poi auto-eliminati
- ✓ Media Protection: File obfuscati e auto-eliminati dopo consegna
- ✓ Screenshot Blocking: FLAG_SECURE su Android per protezione schermo
🏗️ Architettura del Sistema
┌────────────────────────────────────────────┐
│ Kotlin Android Client (MVVM) │
│ - Material Design 3 UI │
│ - Room Database (SQLite) │
│ - Retrofit 2 + OkHttp 4 │
│ - Kotlin Coroutines + Flow │
└────────────────────────────────────────────┘
│
│ HTTPS/WSS (TLS 1.2+)
▼
┌──────────────────┐ ┌──────────────────────┐
│ REST API │ │ WebSocket Server │
│ (PHP 8.0+) │ │ (Go 1.21+) │
│ - JWT Auth │ │ - Gorilla WebSocket │
│ - Bcrypt Hash │ │ - Real-time Msgs │
│ - Media Upload │ │ - Channel-based │
│ - Rate Limiting │ │ - Session Mgmt │
└──────────────────┘ └──────────────────────┘
│ │
└─────────┬─────────┘
▼
┌────────────────────────────────────────────┐
│ MariaDB 10.5+ Database │
│ - users, contacts, groups │
│ - Pending messages (temp, auto-delete) │
│ - media (encrypted files) │
│ - Connection pooling │
└────────────────────────────────────────────┘
💡 NOTA: I messaggi in tempo reale NON toccano
il database! Vanno direttamente da client a
client via WebSocket. Solo messaggi pending
(destinatario offline) salvati temporaneamente.
💻 Tech Stack Completo
Client Android (Kotlin)
// Versione App: 1.2.9 (versionCode: 10209)
Min SDK: 24 (Android 7.0)
Target SDK: 34 (Android 14)
Kotlin: 2.0+
Jetpack Compose: UI moderna
// Librerie principali
- Room Database: v2.6+ (SQLite wrapper)
- Retrofit 2: HTTP client
- OkHttp 4: WebSocket + networking
- Kotlin Coroutines: Async operations
- Flow: Reactive streams
- Material Design 3: UI components
- Glide: Image loading
- ExoPlayer: Video/audio playbackServer Backend
// WebSocket Server (Go)
Go 1.21+
Gorilla WebSocket library
Channel-based message routing
Concurrent connection handling
// REST API (PHP)
PHP 8.0+
Custom MVC architecture
JWT HS256 tokens (7-day expiration)
Bcrypt password hashing (cost 12)
Rate limiting middleware
// Database
MariaDB 10.5+ / MySQL 8.0+
InnoDB engine
Connection pooling
Indexed queries🗄️ Database Schema
Tabelle Principali
// users
- id (PRIMARY KEY)
- username (UNIQUE)
- password_hash (bcrypt)
- nickname
- profile_picture
- created_at
// messages
- id (PRIMARY KEY)
- sender_id (FK → users.id)
- recipient_id (FK → users.id)
- group_id (FK → groups.id, nullable)
- content (TEXT)
- media_id (FK → media.id, nullable)
- timestamp
- delivered_at, read_at
INDEX: (recipient_id, timestamp), (sender_id, timestamp)
// groups
- id (PRIMARY KEY)
- group_name
- description
- mode (ENUM: 'OPEN', 'RESTRICTED')
- created_by (FK → users.id)
- created_at
// group_members
- group_id (FK → groups.id)
- user_id (FK → users.id)
- role (ENUM: 'ADMIN', 'MEMBER')
- joined_at
PRIMARY KEY: (group_id, user_id)
// contacts
- user_id (FK → users.id)
- contact_id (FK → users.id)
- status (ENUM: 'PENDING', 'ACCEPTED', 'BLOCKED')
- requested_at, accepted_at
// media
- id (PRIMARY KEY)
- uploader_id (FK → users.id)
- filename (UUID obfuscated)
- file_size
- media_type (image/video/document)
- uploaded_at
// NOTA IMPORTANTE: messages table
La tabella 'messages' viene utilizzata SOLO per:
1. Messaggi pending (destinatario offline)
2. Backup temporaneo pre-consegna
3. Auto-eliminazione post-consegna
I messaggi in tempo reale vanno DIRETTAMENTE
da client a client via WebSocket SENZA persistenza!💬 Flusso Messaggi - Architettura Privacy-First
Messaggio Real-Time (Destinatario Online)
1. Client A → WebSocket Server (Go)
Payload: { type: "message", recipient_id: 123, content: "..." }
2. Server identifica Client B (online)
3. Server → Client B (DIRETTO, NO database!)
Payload: { type: "message", sender_id: 456, content: "..." }
4. Client B salva in Room Database locale
5. Server conferma consegna a Client A
✅ RISULTATO: Messaggio MAI salvato sul server!
Solo transito in memoria del processo Go.Messaggio Offline (Destinatario Non Connesso)
1. Client A → WebSocket Server
2. Server verifica: Client B offline
3. Server salva TEMPORANEAMENTE in database
INSERT INTO messages (sender_id, recipient_id, content, ...)
4. Client B si connette → Server invia pending messages
5. Client B conferma ricezione
6. Server ELIMINA messaggio da database
DELETE FROM messages WHERE id = ...
✅ RISULTATO: Persistenza minima, solo per garantire consegna!Vantaggi Privacy
- No Chat History sul Server: Il server non mantiene cronologia conversazioni
- Memoria Volatile: Messaggi real-time esistono solo in RAM del processo WebSocket
- Auto-Cleanup: Messaggi pending eliminati immediatamente post-consegna
- Client-Side Storage: Solo il client Room Database ha la storia completa
- Data Minimization: Conformità GDPR - raccolta dati minima necessaria
👥 Sistema Gruppi
Modalità Gruppo
// OPEN Mode
- Tutti i membri possono inviare messaggi
- Tutti vedono i messaggi di tutti
- Admin gestiscono membri e impostazioni
// RESTRICTED Mode
- Solo ADMIN possono inviare messaggi
- Membri possono solo leggere
- Utile per canali di annunci/broadcastRuoli Membri
// ADMIN
- Aggiungere/rimuovere membri
- Promuovere membri ad admin
- Modificare nome/descrizione/modalità gruppo
- Eliminare gruppo (solo creatore)
- Inviare messaggi (sempre)
// MEMBER
- Ricevere messaggi
- Inviare messaggi (solo in modalità OPEN)
- Uscire dal gruppo🛡️ Sicurezza e Autenticazione
JWT Authentication
// Token Structure
Algorithm: HS256
Expiration: 7 days
Refresh: /auth/refresh endpoint
// Payload
{
"user_id": 123,
"username": "mario",
"iat": 1697385600,
"exp": 1697990400
}
// Header requirement
Authorization: Bearer <jwt_token>Password Security
// Bcrypt Hashing
Cost factor: 12
Salt: Auto-generated per password
Storage: VARCHAR(255) for hash
// Validation
- Minimum 6 characters
- Server-side bcrypt verificationRate Limiting
// Endpoints limits (per IP)
/auth/*: 10 requests/minute
/api/v2/*: 100 requests/minute
/media/*: 20 requests/minute
WebSocket messages: 50/minute
// Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1697385660📱 Client Android - Dettagli
Architettura MVVM
// Structure
View (Activity/Fragment)
↓
ViewModel (business logic)
↓
Repository (data layer)
↓
Room Database + Retrofit API
// Dependency Injection
Manual DI pattern
Singleton instances for repositoriesRoom Database (Local)
// Database Version: 5
@Database(
entities = [User, Message, Group, Contact, Media],
version = 5
)
// DAOs
- UserDao: User CRUD operations
- MessageDao: Insert, query, delete messages
- GroupDao: Group management
- ContactDao: Contact list operations
// Offline-first approach
- All data cached locally
- Sync with server on connection
- Queue unsent messagesNetwork Layer
// Retrofit Configuration
Base URL: https://shutappchat.fabiodirauso.it/api/v2/
Timeout: 30s
Interceptors: JWT token injection
// OkHttp WebSocket
URL: wss://shutappchat.fabiodirauso.it/ws
Reconnection: Exponential backoff
Ping/Pong: 30s keepaliveProtocollo WebSocket
Endpoint: wss://shutappchat.fabiodirauso.it/ws
Connessione
// Handshake
Client Server:
{
"type": "auth",
"token": "JWT_TOKEN_HERE"
}
Server Client:
{
"type": "auth_success",
"user_id": 12345,
"session_id": "abc123xyz"
}Invio Messaggio
// Client Server
{
"type": "message",
"recipient_id": 67890,
"encrypted_content": "base64_encrypted_message",
"encrypted_key": "base64_encrypted_aes_key",
"iv": "base64_iv",
"auth_tag": "base64_auth_tag",
"timestamp": 1697385600000
}
// Server Destinatario (se online)
{
"type": "message_received",
"sender_id": 12345,
"message_id": "msg_abc123",
"encrypted_content": "...",
"encrypted_key": "...",
"timestamp": 1697385600000
}Eventi Real-time
typing: Notifica digitazioneread_receipt: Conferma letturadelivery_receipt: Conferma consegnapresence: Stato online/offline
Gestione Media Files
Privacy Features
- Offuscamento Nomi File: UUID random invece di nomi originali
- Storage Crittografato: File salvati come blob crittografati
- Auto-Eliminazione: Cancellazione automatica post visualizzazione
- No Metadata: EXIF data stripped prima dell'upload
Chunked Upload
// Per file > 10MB
1. Client divide file in chunks da 256KB
2. Critta ogni chunk separatamente
3. Upload sequenziale con progress tracking
4. Server riassembla post-upload completoSecurity Features Implementate
Protezione Screenshot (Android)
// .NET MAUI Implementation
Window.AddFlags(WindowManagerFlags.Secure);
// Previene screenshot e screen recordingMedia Protection
File salvati in app private storage, non accessibili da altre app o galleria.
Self-Destructing Messages
// Timer-based deletion
{
"ttl": 3600, // seconds
"delete_after_read": true
}File Name Obfuscation
Pattern: SHUTAPP_[UUID]_[timestamp].enc
Librerie Client (In Sviluppo)
.NET/C# Client
// NuGet Package (Coming Soon)
Install-Package ShutAppChat.Client
// Usage
var client = new ShutAppChatClient("wss://shutappchat.fabiodirauso.it/ws");
await client.AuthenticateAsync(username, password);
await client.SendMessageAsync(recipientId, "Hello, World!");JavaScript/TypeScript SDK
// NPM Package (Roadmap 2026)
npm install shutappchat-sdk
import { ShutAppClient } from 'shutappchat-sdk';
const client = new ShutAppClient();
await client.connect(token);📄 Riferimenti e Documentazione
Per informazioni dettagliate consulta:
📚 Documentazione Disponibile
- API Reference completa - Tutti gli endpoint REST e WebSocket
- Guida Utente - Istruzioni per utilizzare l'app
- Versioni e Changelog - Storia aggiornamenti
- Supporto Tecnico - Assistenza e bug reporting
🔧 Repository e Codice
ShutAppChat è un progetto sviluppato da Fabio Di Rauso.
// URLs Progetto
Website: https://shutappchat.fabiodirauso.it
API: https://shutappchat.fabiodirauso.it/api/v2/
Admin: https://shutappchat.fabiodirauso.it/admin/
GitHub: https://github.com/Underdomotic/shutappchat-clientHai domande tecniche?
Contatta il team di sviluppo per supporto tecnico o contributi al progetto.
Contatta Supporto Tecnico