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

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:

// 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:

// 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):

// 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

// 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

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

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

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

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

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

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

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

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:

// Basic Auth
username: "user@truemail.sk"
password: "user-email-password"

JMAP Session:

// 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:

// 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:

// 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:

// 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:

// 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:

// 5 pokusov za 15 minút
loginRateLimiter: {
  windowMs: 15 * 60 * 1000,
  max: 5
}

API protection:

// Development: 1000 req/15min
// Production: 100 req/15min
apiRateLimiter: {
  windowMs: 15 * 60 * 1000,
  max: process.env.NODE_ENV === 'production' ? 100 : 1000
}

Sensitive operations:

// Password changes, email changes
// Production: 3 pokusy za 15 minút
sensitiveOperationLimiter: { max: 3 }

4. HTTP Security Headers (Helmet)

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é:

// 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:

// ✅ Bezpečné - parametrizované query
await db.select()
  .from(users)
  .where(eq(users.username, username))  // ← automaticky escaped

7. CORS Configuration

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á:

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

npm install

2. Konfigurácia Environment Variables

Skopírujte .env.example do .env a upravte hodnoty:

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):

docker compose up -d postgres

Vygenerujte a aplikujte migrácie:

npm run db:generate
npm run db:migrate

4. Seed Admin Account

Vytvorte prvý admin účet:

npm run db:seed

DÔLEŽITÉ: Uložte si vygenerované temporary password!

5. Spustenie Servera

Development mode:

npm run dev

Production mode:

npm start

Server beží na http://localhost:5000

API Endpointy

Public Endpoints

Login

POST /api/auth/login
Content-Type: application/json

{
  "username": "admin",
  "password": "temporary-password"
}

Response:

{
  "success": true,
  "data": {
    "user": { ... },
    "tokens": {
      "accessToken": "...",
      "refreshToken": "..."
    },
    "needsPasswordChange": true,
    "needsEmailSetup": true
  }
}

Protected Endpoints (vyžadujú JWT token)

Set New Password (Krok 2)

POST /api/auth/set-password
Authorization: Bearer <token>
Content-Type: application/json

{
  "newPassword": "NewSecurePass123!",
  "confirmPassword": "NewSecurePass123!"
}
POST /api/auth/link-email
Authorization: Bearer <token>
Content-Type: application/json

{
  "email": "user@example.com"
}

Skip Email Setup

POST /api/auth/skip-email
Authorization: Bearer <token>

Get Current User

GET /api/auth/me
Authorization: Bearer <token>

Logout

POST /api/auth/logout
Authorization: Bearer <token>

Admin Endpoints (vyžadujú admin rolu)

Create User

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

GET /api/admin/users
Authorization: Bearer <admin-token>

Get User by ID

GET /api/admin/users/:userId
Authorization: Bearer <admin-token>

Change User Role

PATCH /api/admin/users/:userId/role
Authorization: Bearer <admin-token>
Content-Type: application/json

{
  "role": "admin"
}

Delete User

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

# 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:

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

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

# 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
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

EXPOSE 5000

CMD ["npm", "start"]
# 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:


📄 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! 🚀

Description
No description provided
Readme 5.5 MiB
Languages
JavaScript 92%
HTML 7.9%
Dockerfile 0.1%