Files
crm-server/README.md
2025-11-19 08:45:37 +01:00

1249 lines
31 KiB
Markdown

# CRM Server API
Modern backend API server pre CRM systém s pokročilou autentifikáciou, JMAP email integráciou, kontakt managementom a kompletnou bezpečnostnou vrstvou.
## 📋 Obsah
- [Technológie](#technológie)
- [Funkcie](#funkcie)
- [Systém rolí a autorizácia](#systém-rolí-a-autorizácia)
- [Architektúra](#architektúra)
- [Databázová schéma](#databázová-schéma)
- [API Endpoints](#api-endpoints)
- [JMAP Email integrácia](#jmap-email-integrácia)
- [Bezpečnosť](#bezpečnosť)
- [Inštalácia a spustenie](#inštalácia-a-spustenie)
- [Štruktúra projektu](#štruktúra-projektu)
- [Testing](#testing)
- [Deployment](#deployment)
---
## 🚀 Technológie
### Backend Stack
- **Node.js 18+** - Runtime environment
- **Express.js 4.21** - Web framework
- **PostgreSQL 16** - Relačná databáza
- **Drizzle ORM 0.44** - Type-safe ORM
- **JWT (jsonwebtoken 9.0)** - Token-based autentifikácia
- **Bcrypt.js 3.0** - Password hashing
- **Zod 4.1** - Schema validation
- **Axios 1.13** - HTTP client pre JMAP
### Security & Middleware
- **Helmet 8.0** - HTTP security headers (CSP, HSTS)
- **CORS 2.8** - Cross-Origin Resource Sharing
- **Express Rate Limit 8.2** - Rate limiting protection
- **Cookie Parser 1.4** - Cookie parsing
- **Morgan 1.10** - HTTP request logger
- **XSS Clean 0.1** - XSS protection
### Dev Tools
- **Nodemon 3.1** - Auto-restart development server
- **Drizzle Kit 0.31** - Database migrations
- **ESLint** - Code linting
- **Jest 29.7** - Testing framework
- **Supertest 6.3** - HTTP API testing
### Email Integration
- **JMAP Protocol** - Modern email protocol
- **Truemail.sk** - Email provider integration
---
## ✨ Funkcie
### Autentifikácia a používatelia
-**3-krokový onboarding flow**
- Krok 1: Login s dočasným heslom
- Krok 2: Nastavenie vlastného hesla
- Krok 3: Voliteľné pripojenie JMAP email účtu
-**Session-based autentifikácia**
- JWT tokens (Access + Refresh)
- HttpOnly cookies pre bezpečnosť
- Automatický refresh tokenov
-**User management (Admin)**
- Vytvorenie používateľa s automatickým temp heslom
- Zmena rolí (admin/member)
- Zmazanie používateľa
- Zoznam všetkých používateľov
### Email Management (JMAP)
-**Email synchronizácia**
- Stiahnutie emailov z JMAP servera (Truemail.sk)
- Automatická synchronizácia len pre pridané kontakty
- Thread-based organizácia (konverzácie)
-**Email operácie**
- Označovanie ako prečítané/neprečítané
- Vyhľadávanie v emailoch (subject, body, sender)
- Odpovede na emaily cez JMAP
- Počítadlo neprečítaných správ
-**Contact Management**
- Objavovanie potenciálnych kontaktov z email odosielateľov
- Pridávanie kontaktov
- Editácia kontaktov (meno, poznámky)
- Odstránenie kontaktu
- Pri pridaní kontaktu sa automaticky syncujú všetky jeho emaily
### Audit a Logging
-**Kompletný audit trail**
- Všetky dôležité akcie logované do DB
- IP adresa, user agent, timestamp
- Staré a nové hodnoty (pre change tracking)
- Success/error status
-**Audit events**
- Login/logout
- Password changes
- Email linking
- Contact additions/removals
- Role changes (admin akcie)
---
## 🔐 Systém rolí a autorizácia
### Role Hierarchy
#### 1. **Admin**
**Plné oprávnenia:**
- ✅ Všetko čo môže Member
-**User management:**
- `POST /api/admin/users` - Vytvorenie používateľa
- `GET /api/admin/users` - Zoznam všetkých používateľov
- `GET /api/admin/users/:id` - Detail používateľa
- `PATCH /api/admin/users/:id/role` - Zmena role
- `DELETE /api/admin/users/:id` - Zmazanie používateľa
**Backend implementácia:**
```javascript
// Middleware chain
router.use(authenticate); // Overí JWT token
router.use(requireAdmin); // Overí role === 'admin'
```
#### 2. **Member**
**Základné oprávnenia:**
- ✅ Vlastný profil a nastavenia
- ✅ Zmena vlastného hesla
- ✅ Pripojenie vlastného email účtu
- ✅ Správa vlastných kontaktov
- ✅ Vlastné emaily a konverzácie
**NEMÁ prístup k:**
- ❌ Admin endpointy (`/api/admin/*`)
- ❌ Údaje iných používateľov
- ❌ Zmena rolí
### Middleware Chain
**Autentifikácia:**
```javascript
// src/middlewares/auth/authMiddleware.js
export const authenticate = async (req, res, next) => {
// 1. Získaj token z cookie alebo Authorization header
// 2. Verifikuj JWT token
// 3. Načítaj user z DB
// 4. Pridaj user do req.user
}
```
**Autorizácia (role-based):**
```javascript
// src/middlewares/auth/roleMiddleware.js
export const requireAdmin = (req, res, next) => {
if (req.user.role !== 'admin') {
return res.status(403).json({ error: 'Forbidden' })
}
next()
}
```
### Bezpečnostný princíp: Backend Filtering
**✅ Správne:** Backend filtruje dáta podľa role
```javascript
// Admin endpoint - middleware blokuje non-adminov
router.get('/api/admin/users', authenticate, requireAdmin, getAllUsers)
// Member endpoint - user vidí len svoje dáta
router.get('/api/contacts', authenticate, async (req, res) => {
// Service layer filtruje podľa req.user.id
const contacts = await getContactsByUserId(req.user.id)
res.json({ data: contacts })
})
```
**❌ Zlé:** Posielanie všetkých dát a filtrovanie na frontende
- Citlivé admin dáta by boli viditeľné v Network tab
- Security by bola len "visual" - nie skutočná
---
## 🏗️ Architektúra
### Layered Architecture
```
┌─────────────────────────────────────┐
│ Routes Layer │ ← API endpoints, middleware chains
│ (auth.routes.js, admin.routes.js) │
└──────────────┬──────────────────────┘
┌──────────────▼──────────────────────┐
│ Controllers Layer │ ← Request handling, validation
│ (auth.controller.js, ...) │
└──────────────┬──────────────────────┘
┌──────────────▼──────────────────────┐
│ Services Layer │ ← Business logic
│ (auth.service.js, jmap.service.js)│
└──────────────┬──────────────────────┘
┌──────────────▼──────────────────────┐
│ Database Layer (Drizzle ORM) │ ← Data persistence
│ (schema.js) │
└─────────────────────────────────────┘
```
### Middleware Pipeline
```
Request
├─→ Morgan (logging)
├─→ Helmet (security headers)
├─→ CORS (cross-origin)
├─→ Body Parser (JSON, URL-encoded)
├─→ Cookie Parser
├─→ Rate Limiter
├─→ Route Matching
│ │
│ ├─→ authenticate (JWT validation)
│ ├─→ requireAdmin (role check)
│ ├─→ validateBody (Zod schemas)
│ ├─→ Controller
│ └─→ Service → Database
├─→ Not Found Handler (404)
└─→ Error Handler (global catch)
```
---
## 💾 Databázová schéma
### Users Table
```sql
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username TEXT NOT NULL UNIQUE,
email TEXT UNIQUE, -- JMAP email (Truemail.sk)
email_password TEXT, -- Encrypted JMAP password
jmap_account_id TEXT, -- JMAP account ID
first_name TEXT,
last_name TEXT,
password TEXT, -- Bcrypt hash (permanent)
temp_password TEXT, -- Bcrypt hash (temporary)
changed_password BOOLEAN DEFAULT false,
role role_enum DEFAULT 'member' NOT NULL, -- 'admin' | 'member'
last_login TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
```
### Contacts Table
```sql
CREATE TABLE contacts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
email TEXT NOT NULL,
name TEXT,
notes TEXT,
added_at TIMESTAMP DEFAULT NOW(),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
```
### Emails Table
```sql
CREATE TABLE emails (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
contact_id UUID REFERENCES contacts(id) ON DELETE CASCADE,
jmap_id TEXT UNIQUE, -- JMAP message ID
message_id TEXT UNIQUE, -- Email Message-ID header
thread_id TEXT, -- Thread grouping
in_reply_to TEXT, -- Reply chain
"from" TEXT,
"to" TEXT,
subject TEXT,
body TEXT,
is_read BOOLEAN DEFAULT false,
date TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
```
### Audit Logs Table
```sql
CREATE TABLE audit_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
action TEXT NOT NULL, -- 'login', 'password_change', ...
resource TEXT NOT NULL, -- 'user', 'contact', 'email'
resource_id TEXT,
old_value TEXT, -- JSON string
new_value TEXT, -- JSON string
ip_address TEXT,
user_agent TEXT,
success BOOLEAN DEFAULT true,
error_message TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
```
### Relationships
- **Users → Contacts** (1:N) - User môže mať viacero kontaktov
- **Users → Emails** (1:N) - User má svoje emaily
- **Contacts → Emails** (1:N) - Email je priradený kontaktu
- **Users → Audit Logs** (1:N) - Audit log pre každú akciu
---
## 📡 API Endpoints
### Autentifikácia (`/api/auth`)
| Method | Endpoint | Auth | Role | Popis |
|--------|----------|------|------|-------|
| POST | `/auth/login` | ❌ | - | Login s temporary alebo permanent heslom |
| POST | `/auth/set-password` | ✅ | - | Nastavenie nového hesla (onboarding) |
| POST | `/auth/link-email` | ✅ | - | Pripojenie JMAP email účtu |
| POST | `/auth/skip-email` | ✅ | - | Preskočenie email setupu |
| POST | `/auth/logout` | ✅ | - | Odhlásenie (clear cookies) |
| GET | `/auth/session` | ✅ | - | Získanie aktuálnej session |
| GET | `/auth/me` | ✅ | - | Profil aktuálneho usera |
**Príklad: Login request**
```javascript
POST /api/auth/login
Content-Type: application/json
{
"username": "jan.novak",
"password": "TempPass123!"
}
// Response:
{
"success": true,
"data": {
"user": { "id": "...", "username": "jan.novak", "role": "member" },
"needsPasswordChange": true,
"needsEmailSetup": true
}
}
// + Sets accessToken cookie (httpOnly)
```
---
### Admin (`/api/admin`) - **Len pre adminov**
| Method | Endpoint | Auth | Role | Popis |
|--------|----------|------|------|-------|
| POST | `/admin/users` | ✅ | Admin | Vytvorenie nového používateľa |
| GET | `/admin/users` | ✅ | Admin | Zoznam všetkých používateľov |
| GET | `/admin/users/:userId` | ✅ | Admin | Detail používateľa |
| PATCH | `/admin/users/:userId/role` | ✅ | Admin | Zmena role používateľa |
| DELETE | `/admin/users/:userId` | ✅ | Admin | Zmazanie používateľa |
**Príklad: Vytvorenie používateľa**
```javascript
POST /api/admin/users
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"username": "jana.horvathova",
"firstName": "Jana",
"lastName": "Horvathova",
"email": "jana.horvathova@truemail.sk", // voliteľné
"emailPassword": "jmap-password-123" // voliteľné
}
// Response:
{
"success": true,
"data": {
"user": {
"id": "...",
"username": "jana.horvathova",
"tempPassword": "X9kL#mP2qR4w", // ← Admin si toto skopíruje!
"emailSetup": true // true ak bol email poskytnutý
}
}
}
```
---
### Kontakty (`/api/contacts`)
| Method | Endpoint | Auth | Role | Popis |
|--------|----------|------|------|-------|
| GET | `/contacts` | ✅ | - | Všetky kontakty usera |
| GET | `/contacts/discover` | ✅ | - | Potenciálne kontakty (z JMAP) |
| POST | `/contacts` | ✅ | - | Pridať kontakt + sync jeho emailov |
| PATCH | `/contacts/:id` | ✅ | - | Upraviť kontakt |
| DELETE | `/contacts/:id` | ✅ | - | Odstrániť kontakt |
**Príklad: Objavenie potenciálnych kontaktov**
```javascript
GET /api/contacts/discover?limit=50&search=john
Authorization: Bearer <token>
// Response:
{
"success": true,
"data": [
{
"email": "john.doe@example.com",
"name": "John Doe",
"emailCount": 15,
"isContact": false, // Ešte nie je v kontaktoch
"lastEmailDate": "2024-11-18T10:30:00Z"
},
...
]
}
```
---
### Emaily (`/api/emails`)
| Method | Endpoint | Auth | Role | Popis |
|--------|----------|------|------|-------|
| GET | `/emails` | ✅ | - | Všetky emaily usera |
| GET | `/emails/search?q=...` | ✅ | - | Vyhľadávanie v emailoch |
| GET | `/emails/unread-count` | ✅ | - | Počet neprečítaných emailov |
| POST | `/emails/sync` | ✅ | - | Manuálna synchronizácia z JMAP |
| GET | `/emails/thread/:threadId` | ✅ | - | Thread (konverzácia) |
| POST | `/emails/thread/:threadId/read` | ✅ | - | Označiť thread ako prečítaný |
| GET | `/emails/contact/:contactId` | ✅ | - | Emaily od konkrétneho kontaktu |
| PATCH | `/emails/:jmapId/read` | ✅ | - | Označiť email ako prečítaný |
| POST | `/emails/reply` | ✅ | - | Odpovedať na email cez JMAP |
**Príklad: Odpoveď na email**
```javascript
POST /api/emails/reply
Authorization: Bearer <token>
Content-Type: application/json
{
"to": "john.doe@example.com",
"subject": "Re: Project Update",
"body": "Thanks for the update!",
"inReplyTo": "<message-id@example.com>",
"threadId": "thread-abc123"
}
// Response:
{
"success": true,
"data": {
"messageId": "<new-message-id@truemail.sk>",
"sentAt": "2024-11-18T15:45:00Z"
}
}
```
---
## 📧 JMAP Email integrácia
### Čo je JMAP?
**JMAP (JSON Meta Application Protocol)** je moderný email protocol, náhrada za IMAP/SMTP.
**Výhody:**
- JSON-based API (nie custom text protocol ako IMAP)
- Stateless (REST-like)
- Efektívnejší bandwidth (delta updates)
- Lepší pre mobile aplikácie
### Truemail.sk integrácia
**JMAP Server:** `https://mail.truemail.sk/jmap/`
**Autentifikácia:**
```javascript
// Basic Auth
username: "user@truemail.sk"
password: "user-email-password"
```
**JMAP Session:**
```javascript
// 1. Získaj session info
GET https://mail.truemail.sk/jmap/
Authorization: Basic <base64-credentials>
// Response obsahuje:
{
"accounts": {
"ba": { ... } // ← accountId
},
"apiUrl": "https://mail.truemail.sk/jmap/"
}
```
### Synchronizácia emailov
**Kedy sa syncujú emaily:**
1. ✅ Pri pridaní nového kontaktu - automaticky sa stiahnu všetky jeho emaily
2. ✅ Manuálne cez `POST /api/emails/sync`
3. ✅ Automaticky každých 60 sekúnd (frontend polling)
**Proces:**
```javascript
// Service layer: src/services/jmap.service.js
export const syncContactEmails = async (user, contactEmail) => {
const jmapConfig = getJmapConfig(user)
// 1. JMAP Email/query - nájdi emaily od/pre kontakt
const emailIds = await jmapRequest(jmapConfig, [
['Email/query', {
accountId: jmapConfig.accountId,
filter: {
from: contactEmail
// OR to: contactEmail
}
}]
])
// 2. JMAP Email/get - získaj detaily emailov
const emails = await jmapRequest(jmapConfig, [
['Email/get', {
accountId: jmapConfig.accountId,
ids: emailIds
}]
])
// 3. Ulož do DB (emails table)
await saveEmailsToDB(emails, user.id, contact.id)
}
```
**Thread support:**
- Emaily sú zoskupené podľa `threadId` (JMAP native)
- `inReplyTo` header pre reply chains
- Frontend zobrazuje ako konverzácie
---
## 🔒 Bezpečnosť
### 1. Password Security
**Bcrypt hashing:**
```javascript
// 12 rounds (2^12 iterations)
const hash = await bcrypt.hash(password, 12)
```
**Strong password policy:**
- Minimálne 8 znakov
- Aspoň 1 veľké písmeno
- Aspoň 1 malé písmeno
- Aspoň 1 číslo
- Aspoň 1 špeciálny znak
**Email password encryption:**
```javascript
// AES-256-GCM encryption pre JMAP password
const encrypted = encryptPassword(emailPassword)
// Formát: "iv:authTag:encryptedText"
```
### 2. JWT Token Security
**Access Token:**
- Krátka životnosť (1 hodina)
- HttpOnly cookie (nedostupný pre JavaScript)
- Secure flag (len HTTPS v produkcii)
- SameSite=Strict (CSRF protection)
**Token generation:**
```javascript
// src/utils/jwt.js
export const generateAccessToken = (user) => {
return jwt.sign(
{ id: user.id, role: user.role },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
)
}
```
### 3. Rate Limiting
**Login protection:**
```javascript
// 5 pokusov za 15 minút
loginRateLimiter: {
windowMs: 15 * 60 * 1000,
max: 5
}
```
**API protection:**
```javascript
// Development: 1000 req/15min
// Production: 100 req/15min
apiRateLimiter: {
windowMs: 15 * 60 * 1000,
max: process.env.NODE_ENV === 'production' ? 100 : 1000
}
```
**Sensitive operations:**
```javascript
// Password changes, email changes
// Production: 3 pokusy za 15 minút
sensitiveOperationLimiter: { max: 3 }
```
### 4. HTTP Security Headers (Helmet)
```javascript
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"]
}
},
hsts: {
maxAge: 31536000, // 1 rok
includeSubDomains: true,
preload: true
}
})
```
### 5. Input Validation (Zod)
**Všetky user inputy sú validované:**
```javascript
// src/validators/auth.validators.js
export const loginSchema = z.object({
username: z.string().min(3).max(50),
password: z.string().min(8)
})
// Middleware
validateBody(loginSchema)
```
### 6. SQL Injection Protection
**Drizzle ORM používa prepared statements:**
```javascript
// ✅ Bezpečné - parametrizované query
await db.select()
.from(users)
.where(eq(users.username, username)) // ← automaticky escaped
```
### 7. CORS Configuration
```javascript
cors({
origin: process.env.CORS_ORIGIN || 'http://localhost:5173',
credentials: true, // Povoľ cookies
optionsSuccessStatus: 200
})
```
### 8. Audit Logging
**Každá dôležitá akcia je logovaná:**
```javascript
await logAuditEvent({
userId: user.id,
action: 'login',
resource: 'auth',
ipAddress: req.ip,
userAgent: req.headers['user-agent'],
success: true
})
```
---
## 📦 Inštalácia a spustenie
### Požiadavky
- **Node.js 18+** a **npm 9+**
- **PostgreSQL 16+**
- **Docker** (voliteľné, pre lokálne DB)
## Inštalácia
### 1. Klonovanie a Dependencies
```bash
npm install
```
### 2. Konfigurácia Environment Variables
Skopírujte `.env.example` do `.env` a upravte hodnoty:
```bash
cp .env.example .env
```
Dôležité premenné:
- `JWT_SECRET` - Zmeňte v produkcii!
- `JWT_REFRESH_SECRET` - Zmeňte v produkcii!
- `BETTER_AUTH_SECRET` - Zmeňte v produkcii!
- `DB_*` - Databázové credentials
- `JMAP_*` - Email server credentials
### 3. Databáza Setup
Spustite PostgreSQL (Docker):
```bash
docker compose up -d postgres
```
Vygenerujte a aplikujte migrácie:
```bash
npm run db:generate
npm run db:migrate
```
### 4. Seed Admin Account
Vytvorte prvý admin účet:
```bash
npm run db:seed
```
**DÔLEŽITÉ:** Uložte si vygenerované temporary password!
### 5. Spustenie Servera
Development mode:
```bash
npm run dev
```
Production mode:
```bash
npm start
```
Server beží na `http://localhost:5000`
## API Endpointy
### Public Endpoints
#### Login
```http
POST /api/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "temporary-password"
}
```
**Response:**
```json
{
"success": true,
"data": {
"user": { ... },
"tokens": {
"accessToken": "...",
"refreshToken": "..."
},
"needsPasswordChange": true,
"needsEmailSetup": true
}
}
```
### Protected Endpoints (vyžadujú JWT token)
#### Set New Password (Krok 2)
```http
POST /api/auth/set-password
Authorization: Bearer <token>
Content-Type: application/json
{
"newPassword": "NewSecurePass123!",
"confirmPassword": "NewSecurePass123!"
}
```
#### Link Email (Krok 3)
```http
POST /api/auth/link-email
Authorization: Bearer <token>
Content-Type: application/json
{
"email": "user@example.com"
}
```
#### Skip Email Setup
```http
POST /api/auth/skip-email
Authorization: Bearer <token>
```
#### Get Current User
```http
GET /api/auth/me
Authorization: Bearer <token>
```
#### Logout
```http
POST /api/auth/logout
Authorization: Bearer <token>
```
### Admin Endpoints (vyžadujú admin rolu)
#### Create User
```http
POST /api/admin/users
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"username": "newuser",
"tempPassword": "TempPass123!",
"role": "member",
"firstName": "John",
"lastName": "Doe"
}
```
#### Get All Users
```http
GET /api/admin/users
Authorization: Bearer <admin-token>
```
#### Get User by ID
```http
GET /api/admin/users/:userId
Authorization: Bearer <admin-token>
```
#### Change User Role
```http
PATCH /api/admin/users/:userId/role
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"role": "admin"
}
```
#### Delete User
```http
DELETE /api/admin/users/:userId
Authorization: Bearer <admin-token>
```
## Databázová Schéma
### Users Table
```
- id (UUID)
- username (unique)
- email (unique, nullable)
- email_verified (boolean)
- first_name
- last_name
- password (bcrypt hash)
- temp_password (bcrypt hash)
- changed_password (boolean)
- role (enum: admin, member)
- last_login
- created_at
- updated_at
```
### Sessions Table
```
- id (text)
- user_id (UUID, FK)
- expires_at
- ip_address
- user_agent
- created_at
```
### Audit Logs Table
```
- id (UUID)
- user_id (UUID, FK, nullable)
- action
- resource
- resource_id
- old_value (JSON)
- new_value (JSON)
- ip_address
- user_agent
- success (boolean)
- error_message
- created_at
```
## Validačné Pravidlá
### Password Policy
- Minimálne 8 znakov
- Aspoň 1 veľké písmeno
- Aspoň 1 malé písmeno
- Aspoň 1 číslo
- Aspoň 1 špeciálny znak
### Username Policy
- 3-50 znakov
- Iba písmená, čísla, pomlčky a podčiarkovníky
## Rate Limiting
- **Login endpoint:** 5 pokusov / 15 minút
- **API endpoints:** 100 requestov / 15 minút
- **Citlivé operácie:** 3 pokusy / 15 minút
## Audit Logging
Všetky dôležité akcie sú automaticky logované:
- Login attempts (úspešné aj neúspešné)
- Password changes
- Email linking & verification
- Role changes
- User creation
- A ďalšie...
## Security Best Practices
1. **HTTPS Only** - V produkcii vždy používajte HTTPS
2. **Strong Secrets** - Zmeňte všetky secret keys v `.env`
3. **Regular Updates** - Aktualizujte dependencies
4. **Monitor Logs** - Sledujte audit logs
5. **Backup Database** - Pravidelné zálohy PostgreSQL
## Database Commands
```bash
# Generovanie migrácií
npm run db:generate
# Aplikovanie migrácií
npm run db:migrate
# Push schema (alternative to migrations)
npm run db:push
# Drizzle Studio (GUI)
npm run db:studio
# Seed admin account
npm run db:seed
```
## Testing
Spustenie testov:
```bash
npm test
```
## 📁 Štruktúra projektu
```
crm-server/
├── src/
│ ├── api/ # (unused, legacy?)
│ ├── config/
│ │ ├── database.js # Drizzle DB connection
│ │ └── jmap.js # JMAP configuration
│ │
│ ├── controllers/ # Request handlers
│ │ ├── auth.controller.js # Login, set password, link email
│ │ ├── admin.controller.js # User management (admin only)
│ │ ├── contact.controller.js # Contact CRUD
│ │ └── crm-email.controller.js # Email sync, search, replies
│ │
│ ├── db/
│ │ ├── schema.js # Drizzle tables (users, contacts, emails, audit_logs)
│ │ ├── migrate.js # Migration runner
│ │ ├── migrations/ # Auto-generated SQL migrations
│ │ └── seeds/
│ │ ├── admin.seed.js # Seed admin account
│ │ └── testuser.seed.js # Seed test user
│ │
│ ├── middlewares/
│ │ ├── auth/
│ │ │ ├── authMiddleware.js # JWT validation (authenticate)
│ │ │ └── roleMiddleware.js # Role check (requireAdmin, requireOwnerOrAdmin)
│ │ ├── security/
│ │ │ ├── rateLimiter.js # Login, API, sensitive operation limiters
│ │ │ └── validateInput.js # Zod schema validation
│ │ └── global/
│ │ ├── errorHandler.js # Global error handler
│ │ ├── notFound.js # 404 handler
│ │ └── validateBody.js # Body validation
│ │
│ ├── routes/ # API route definitions
│ │ ├── auth.routes.js # /api/auth/* (login, set-password, link-email)
│ │ ├── admin.routes.js # /api/admin/* (user management)
│ │ ├── contact.routes.js # /api/contacts/* (CRUD)
│ │ └── crm-email.routes.js # /api/emails/* (sync, search, reply)
│ │
│ ├── services/ # Business logic layer
│ │ ├── auth.service.js # User authentication, password management
│ │ ├── contact.service.js # Contact management
│ │ ├── crm-email.service.js # Email database operations
│ │ ├── jmap.service.js # JMAP API integration (Truemail.sk)
│ │ ├── email.service.js # Email utilities
│ │ └── audit.service.js # Audit logging
│ │
│ ├── validators/ # Zod validation schemas
│ │ └── auth.validators.js # Login, password, email schemas
│ │
│ ├── utils/ # Helper utilities
│ │ ├── errors.js # Custom error classes
│ │ ├── jwt.js # JWT generation & verification
│ │ ├── logger.js # Logging utility
│ │ └── password.js # Bcrypt hashing, temp password generation, encryption
│ │
│ ├── app.js # Express app configuration
│ └── index.js # Server entry point
├── __tests__/ # Jest test files
├── postgres/ # Docker volume for PostgreSQL data
├── .env.example # Environment variables template
├── .env # Environment variables (gitignored)
├── docker-compose.yml # PostgreSQL Docker setup
├── drizzle.config.js # Drizzle Kit configuration
├── package.json # NPM dependencies and scripts
└── README.md # This file
```
### Kľúčové súbory
**`src/app.js`**
- Express aplikácia setup
- Middleware chain (security, CORS, parsing, rate limiting)
- Route mounting
- Global error handling
**`src/db/schema.js`**
- Drizzle ORM schema definície
- Tables: users, contacts, emails, audit_logs
- Relationships a indexy
**`src/services/jmap.service.js`**
- JMAP API client pre Truemail.sk
- Email sync, search, send reply
- Mailbox management
**`src/middlewares/auth/authMiddleware.js`**
- JWT token validation
- User session loading
- Pridáva `req.user` do requestu
**`src/middlewares/auth/roleMiddleware.js`**
- Role-based access control
- `requireAdmin` - blokuje non-adminov
- `requireOwnerOrAdmin` - vlastník alebo admin
---
## 🧪 Testing
### Spustenie testov
```bash
npm test
```
### Test coverage (TODO)
- Unit testy pre services
- Integration testy pre API endpoints
- E2E testy pre autentifikačný flow
---
## 🚀 Deployment
### Production Checklist
**1. Environment Variables**
```bash
# Zmeň všetky secret keys!
JWT_SECRET=<strong-random-key>
JWT_REFRESH_SECRET=<strong-random-key>
BETTER_AUTH_SECRET=<strong-random-key>
# Production settings
NODE_ENV=production
CORS_ORIGIN=https://your-frontend-domain.com
RATE_LIMIT_MAX_REQUESTS=100
# Database
DB_HOST=your-production-db-host
DB_PORT=5432
DB_USER=crm_user
DB_PASSWORD=<strong-db-password>
DB_NAME=crm_production
```
**2. HTTPS Setup**
- Použite reverse proxy (Nginx, Caddy)
- SSL certifikáty (Let's Encrypt)
- Redirect HTTP → HTTPS
**3. Database**
- Povolte SSL connections
- Pravidelné backupy (pg_dump)
- Monitoring (pg_stat_statements)
**4. Security**
- Firewall rules (povoľ len potrebné porty)
- DDoS protection (Cloudflare, AWS Shield)
- Monitoring a alerting (Sentry, DataDog)
**5. Deployment Platforms**
- **VPS:** DigitalOcean, Linode, Vultr
- **Cloud:** AWS (EC2, RDS), Google Cloud, Azure
- **Platform:** Railway, Render, Fly.io
### Docker Deployment
```dockerfile
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 5000
CMD ["npm", "start"]
```
```bash
# Build
docker build -t crm-server .
# Run
docker run -d \
--name crm-api \
-p 5000:5000 \
--env-file .env \
crm-server
```
---
## 📝 TODO / Budúce vylepšenia
- [ ] Refresh token rotation
- [ ] Email verification (2FA)
- [ ] Password reset flow
- [ ] User profile pictures
- [ ] Advanced audit log filtering
- [ ] Webhook support
- [ ] Real-time notifications (WebSockets)
- [ ] Multi-tenant support
- [ ] API rate limiting per user
- [ ] Automated backup system
---
## 🐛 Known Issues
- JMAP sync môže byť pomalý pri veľkom množstve emailov (optimalizovať batch size)
- Rate limiter je in-memory (nepersistuje cez reštarty) - zvážiť Redis
- Session refresh token nemá automatic rotation
---
## 📞 Podpora a Kontakt
Pre technické otázky a bug reporting:
- Vytvor Issue v repozitári
- Email: richard@example.com
---
## 📄 Licencia
MIT License
Copyright (c) 2024 Richard Tekula
---
## 👨‍💻 Autor
**Richard Tekula**
Backend Developer
---
**⚠️ PRODUCTION WARNING:**
Tento projekt je v aktívnom vývoji. Pred production deploymentom nezabudni:
1. ✅ Zmeniť všetky secret keys v `.env`
2. ✅ Nastaviť HTTPS (reverse proxy)
3. ✅ Konfigurovať firewall pravidlá
4. ✅ Nastaviť monitoring a alerting (Sentry, Prometheus)
5. ✅ Pravidelné security audity (`npm audit`)
6. ✅ Database backupy (automatizované)
7. ✅ Load balancing (pri vysokom trafficu)
8. ✅ CDN pre static assets
9. ✅ GDPR compliance (ak potrebné)
**Happy coding! 🚀**