richardtekula 540c1719d3 Add Time Tracking backend API
Implementovaný kompletný backend pre time tracking:
- Nová tabuľka time_entries s foreign keys na users, projects, todos, companies
- Service layer s business logikou pre CRUD operácie
- Controller pre všetky endpointy
- Validačné schémy pomocou Zod
- Routes s autentifikáciou a validáciou
- Endpointy:
  * POST /api/time-tracking/start - Spustenie timeru
  * POST /api/time-tracking/:id/stop - Zastavenie timeru
  * GET /api/time-tracking/running - Získanie bežiaceho záznamu
  * GET /api/time-tracking/month/:year/:month - Mesačné záznamy
  * GET /api/time-tracking/stats/monthly/:year/:month - Mesačné štatistiky
  * PATCH /api/time-tracking/:id - Aktualizácia záznamu
  * DELETE /api/time-tracking/:id - Zmazanie záznamu
- Podpora pre isEdited flag pri editácii
- Kalkulácia duration v minútach

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 06:41:39 +01:00
2025-11-24 06:41:39 +01:00
2025-11-18 13:53:28 +01:00
2025-11-19 13:21:34 +01:00

CRM Server API

Backend API pre email a kontaktný manažment s podporou viacerých JMAP účtov.

Funkcie

Autentifikácia

  • Login - Session-based auth s JWT tokens (httpOnly cookies)
  • Onboarding - 3-krokový flow (login → nastavenie hesla → pripojenie emailu)
  • Session management - Automatický refresh tokenov
  • Role-based access - Admin a Member

Email účty (Multi-account)

  • Pridanie účtu - Pripojenie viacerých JMAP účtov
  • Šifrovanie hesiel - AES-256-GCM encryption pre JMAP heslá
  • Primárny účet - Označenie hlavného účtu
  • Cascade delete - Odstránenie účtu vymaže všetky jeho dáta

JMAP Email integrácia

  • Sync emailov - Stiahnutie emailov z Truemail.sk JMAP servera
  • Thread organizácia - Emaily zoskupené do konverzácií
  • Full-text search - Vyhľadávanie v predmete, tele, odosielateľovi
  • Posielanie odpovedí - Odpoveď na emaily cez JMAP
  • Neprecítané správy - Počítadlo per účet

Kontakty

  • Objavovanie - Automatické získanie odosielateľov z emailov
  • Auto-sync emailov - Pri pridaní kontaktu sa stiahnu všetky jeho emaily
  • CRUD operácie - Pridanie, úprava, odstránenie
  • Account filtering - Kontakty izolované per email účet

Správa používateľov (Admin)

  • Vytvorenie usera - Auto-generovanie temporary hesla
  • Zmena rolí - Admin/Member
  • Zoznam používateľov - Len pre adminov

Bezpečnosť

  • Password hashing - Bcrypt (12 rounds)
  • Rate limiting - Login, API, citlivé operácie
  • Helmet - HTTP security headers (CSP, HSTS)
  • Input validation - Zod schemas
  • SQL injection protection - Drizzle ORM prepared statements
  • XSS protection - Sanitizácia inputov
  • Audit logging - Všetky dôležité akcie logované

API Endpointy

Autentifikácia /api/auth

  • POST /login - Prihlásenie
  • POST /set-password - Nastavenie hesla (onboarding)
  • POST /change-password - Zmena hesla
  • POST /logout - Odhlásenie
  • GET /session - Získanie session info
  • GET /me - Aktuálny používateľ

Email účty /api/email-accounts

  • GET / - Zoznam účtov
  • POST / - Pridanie účtu
  • DELETE /:id - Odstránenie účtu
  • PATCH /:id/primary - Nastavenie primárneho

Admin /api/admin (Admin only)

  • POST /users - Vytvorenie používateľa
  • GET /users - Zoznam používateľov
  • PATCH /users/:id/role - Zmena role
  • DELETE /users/:id - Zmazanie používateľa

Kontakty /api/contacts

  • GET / - Zoznam kontaktov (s accountId filtrom)
  • GET /discover - Potenciálne kontakty z JMAP
  • POST / - Pridať kontakt + auto-sync emailov
  • PATCH /:id - Upraviť kontakt
  • DELETE /:id - Odstrániť kontakt

Emaily /api/emails

  • GET / - Zoznam emailov (s accountId filtrom)
  • GET /search - Vyhľadávanie v DB
  • GET /search-jmap - JMAP full-text search
  • GET /thread/:id - Thread konverzácie
  • POST /thread/:id/read - Označiť thread ako prečítaný
  • POST /sync - Manuálna synchronizácia
  • POST /reply - Odpovedať na email
  • GET /unread-count - Počet neprecítaných per účet

Services

auth.service.js

Správa autentifikácie a používateľov.

Funkcie:

  • getUserById(id) - Získanie usera z DB podľa ID
  • getUserByUsername(username) - Nájdenie usera podľa username
  • createUser(data) - Vytvorenie nového usera s auto-generovaným temporary heslom
  • validatePassword(user, password) - Validácia hesla (bcrypt compare s temp_password alebo password)
  • changePassword(userId, newPassword) - Zmena hesla + audit log + update changed_password = true
  • updateLastLogin(userId) - Update last_login timestamp

email-account.service.js

Multi-account email management.

Funkcie:

  • getEmailAccounts(userId) - Zoznam všetkých email účtov usera
  • addEmailAccount(userId, email, password) - Pridanie JMAP účtu s validáciou credentials a šifrovaním hesla
  • getEmailAccountWithCredentials(accountId, userId) - Účet s dešifrovaným heslom (pre JMAP operácie)
  • getPrimaryEmailAccount(userId) - Vráti primárny účet usera
  • removeEmailAccount(accountId, userId) - Odstránenie účtu + cascade delete kontaktov a emailov
  • setPrimaryAccount(accountId, userId) - Nastavenie účtu ako primárneho (resetne ostatné)
  • verifyAccountOwnership(accountId, userId) - Overenie že účet patrí userovi

jmap.service.js

JMAP protokol integrácia s Truemail.sk.

Core funkcie:

  • jmapRequest(config, methodCalls) - Low-level JMAP HTTP request (Basic Auth + JSON payload)
  • getJmapSession(config) - Získanie JMAP session (capabilities, accountId, upload URL)
  • getJmapConfigFromAccount(accountId, userId) - Vytvorenie JMAP config objektu z DB account

Email operácie:

  • syncEmailsFromJMAP(config, userId, accountId, filters) - Stiahnutie emailov z JMAP a uloženie do DB
  • syncEmailsFromSender(config, userId, accountId, senderEmail, contactId) - Sync všetkých emailov od konkrétneho odosielateľa
  • searchEmailsJMAP(config, query, limit, offset) - Full-text search v JMAP serveri
  • sendEmail(config, emailAccountId, to, subject, body, inReplyTo) - Vytvorenie a poslanie odpovede cez JMAP
  • markEmailAsRead(config, userId, jmapId, isRead) - Update $seen keywordu na JMAP serveri

Discovery:

  • discoverContactsFromJMAP(config) - Získanie všetkých unikátnych emailových adries z INBOX

Helpers:

  • parseJmapResponse(response) - Parsovanie JMAP response a error handling
  • extractEmailAddress(emailObject) - Extrahovanie email adresy z JMAP formátu [{email: "..."}]

contact.service.js

Správa kontaktov s auto-sync funkciou.

Funkcie:

  • getUserContacts(userId, accountId?) - Zoznam kontaktov usera (s voliteľným account filtrom)
  • getContactById(contactId, userId) - Detail kontaktu s ownership validáciou
  • addContact(userId, accountId, email, name?, notes?) - Pridanie kontaktu + automatický sync emailov od tohto odosielateľa
  • updateContact(contactId, userId, updates) - Update mena alebo poznámok
  • removeContact(contactId, userId) - Odstránenie kontaktu (emaily zostávajú, contact_id = null)
  • verifyContactOwnership(contactId, userId) - Overenie ownership

crm-email.service.js

Email CRUD operácie a thread management.

Funkcie:

  • getUserEmails(userId, accountId?, filters?) - Zoznam emailov s pagination a filtrami (isRead, contactId, search)
  • getEmailById(emailId, userId) - Detail emailu
  • getEmailThread(threadId, userId) - Všetky emaily v konverzácii (sorted by date)
  • markThreadAsRead(threadId, userId, isRead) - Označenie všetkých emailov v threade
  • searchEmails(userId, query, accountId?) - DB full-text search (subject, body, from)
  • getUnreadCount(userId, accountId?) - Počet neprecítaných emailov per účet
  • createEmail(data) - Vytvorenie email záznamu v DB (používa jmap.service)
  • updateEmailReadStatus(emailId, userId, isRead) - Update single email read status

audit.service.js

Audit logging pre bezpečnostné účely.

Funkcia:

  • logAuditEvent(data) - Zaloguje akciu do audit_logs tabuľky
    {
      userId, action, resource, resourceId?,
      oldValue?, newValue?, success,
      errorMessage?, ipAddress?, userAgent?
    }
    

Tracked events:

  • Login (success/fail)
  • Password changes
  • User creation/deletion
  • Email account add/remove
  • Role changes
  • Contact add/remove

email.service.js

(Legacy?) Basic email operácie - možno deprecated v prospech crm-email.service.js

Middlewares

Autentifikácia

authenticate.js

  • Validuje JWT access token z httpOnly cookie
  • Načíta usera z DB a priradí k req.user
  • Ak token expiroval, vráti 401 Unauthorized
  • Ak token chýba, vráti 401 Unauthorized

roleMiddleware.js

requireAdmin

  • Overí že user má role = 'admin'
  • Používa sa pred admin-only endpointmi
  • Vráti 403 Forbidden ak nie je admin

requireOwnerOrAdmin

  • Overí že user je vlastník resource alebo admin
  • Používa sa napr. pri úprave vlastného profilu
  • Parameter: resourceUserId z req.params alebo req.body

Bezpečnosť

rateLimiter.js

loginRateLimiter

  • Limit: 5 pokusov / 15 minút
  • Scope: Per IP adresa
  • Používa sa na /api/auth/login
  • Ochrana proti brute force útokom

apiRateLimiter

  • Limit: 100 requestov / 15 min (production)
  • Limit: 1000 requestov / 15 min (development)
  • Scope: Per IP adresa
  • Aplikuje sa na všetky /api/* routes

sensitiveOperationLimiter

  • Limit: 3 pokusy / 15 minút
  • Používa sa na password change, user delete, atď.
  • Extra ochrana pre kritické operácie

validateInput.js

  • XSS sanitizácia vstupných dát
  • Používa xss-clean knižnicu
  • Automaticky aplikované cez xss-clean middleware

Validácia

validateBody.js

  • Middleware factory pre Zod schema validáciu
  • Použitie: validateBody(schema)
  • Pri validačnej chybe vráti 400 s detailmi

validateParams.js

  • Validácia URL parametrov (napr. :id)
  • Zod schemas pre params

Príklad použitia:

router.post(
  '/login',
  validateBody(loginSchema),
  loginRateLimiter,
  loginController
);

Global

errorHandler.js

  • Centrálne spracovanie všetkých errorov
  • Rozpoznáva custom error classes (BadRequestError, UnauthorizedError, ...)
  • Production: Skryje stack traces
  • Development: Full error details
  • Loguje errory cez Winston

notFound.js

  • 404 handler pre neexistujúce routes
  • Musí byť zaregistrovaný pred errorHandler
  • Vráti: { success: false, error: 'Route not found' }

Database Schema

users

  • id, username, role (admin/member)
  • password, temp_password (bcrypt hash)
  • changed_password, last_login
  • created_at, updated_at

email_accounts

  • id, user_id (FK → users)
  • email, email_password (AES-256 encrypted)
  • jmap_account_id
  • is_primary, is_active
  • created_at, updated_at

contacts

  • id, user_id (FK → users)
  • email_account_id (FK → email_accounts)
  • email, name, notes
  • added_at, created_at, updated_at

emails

  • id, user_id (FK → users)
  • email_account_id (FK → email_accounts)
  • contact_id (FK → contacts)
  • jmap_id, message_id, thread_id
  • from, to, subject, body
  • is_read, date
  • created_at, updated_at

audit_logs

  • id, user_id (FK → users)
  • action, resource, resource_id
  • old_value, new_value (JSON)
  • ip_address, user_agent
  • success, error_message
  • created_at

Konfigurácia

Environment Variables (.env)

# Server Configuration
PORT=5000                    # Port na ktorom beží Express server
NODE_ENV=development         # development | production (ovplyvňuje rate limits, error handling)

# Database Configuration
DB_HOST=localhost           # PostgreSQL host (docker-compose: 'postgres')
DB_PORT=5432               # PostgreSQL port
DB_USER=admin              # DB username
DB_PASSWORD=heslo123       # DB password
DB_NAME=crm                # Database name

# JWT Secrets (MUSIA byť dlhé a náhodné!)
JWT_SECRET=your-secret-key              # Pre access token (min 32 znakov)
JWT_REFRESH_SECRET=your-refresh-secret  # Pre refresh token (min 32 znakov)
JWT_EXPIRES_IN=1h                       # Access token expiration (1h = 1 hodina)

# JMAP Configuration
JMAP_SERVER=https://mail.truemail.sk/jmap/    # JMAP endpoint pre Truemail.sk

# Encryption (pre JMAP heslá)
ENCRYPTION_KEY=your-32-char-encryption-key    # PRESNE 32 znakov pre AES-256

# CORS
CORS_ORIGIN=http://localhost:5173    # Frontend URL (React dev server)

# Optional
BCRYPT_ROUNDS=12                     # Bcrypt cost factor (default: 12)

Ako vygenerovať secrets

JWT_SECRET a JWT_REFRESH_SECRET:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

ENCRYPTION_KEY (presne 32 znakov):

node -e "console.log(require('crypto').randomBytes(32).toString('base64').slice(0, 32))"

Docker Compose

docker-compose.yml obsahuje len PostgreSQL databázu:

services:
  postgres:
    image: postgres:16
    container_name: postgres-db
    restart: "no"
    ports:
      - "5432:5432"
    volumes:
      - ./postgres:/var/lib/postgresql/data

Spustenie:

docker-compose up -d postgres    # Start databázy
docker-compose down              # Stop databázy (data zostanú)
docker-compose down -v           # Stop + vymazanie volumes (⚠️ stratíš dáta)

Drizzle Configuration

drizzle.config.js - Konfigurácia pre Drizzle Kit (migrations tool):

{
  schema: './src/db/schema.js',      // Kde je DB schema definovaná
  out: './src/db/migrations',        // Kam sa uložia migrračné SQL súbory
  dialect: 'postgresql',
  dbCredentials: { /* z .env */ },
  verbose: true,                     // Loguje SQL queries
  strict: true                       // Prísna validácia
}

Používané príkazy:

  • drizzle-kit generate → vygeneruje SQL migrácie zo schémy
  • drizzle-kit push → pushne schému priamo (skip migrations)
  • drizzle-kit studio → otvorí DB GUI na http://localhost:4983

Skripty

NPM Skripty

# Development & Production
npm run dev              # Spustí vývojový server s nodemon (hot reload)
npm start               # Production server (bez reloadovania)

# Database management
npm run db:generate     # Vygeneruje SQL migračné súbory z Drizzle schémy
npm run db:migrate      # Aplikuje migrácie na databázu
npm run db:push         # Pushne schému priamo (bez migračných súborov)
npm run db:studio       # Otvorí Drizzle Studio - GUI pre databázu

# Seeding
npm run db:seed              # Vytvorí admin účet s náhodným heslom
npm run db:seed:testuser     # Vytvorí testovacieho usera (testuser/testuser123!)

# Testing
npm test                # Spustí Jest testy

Utility Skripty

check-tables.js - Zoznam všetkých tabuliek v databáze

node check-tables.js

test-search.js - Test JMAP search endpointu (vyžaduje TEST_COOKIE env)

TEST_COOKIE='session=xyz...' node test-search.js

mark-email-read-jmap.js - Označí konkrétny email ako prečítaný cez JMAP

node mark-email-read-jmap.js

scripts/encrypt-password.js - Zašifruje heslo pre manuálne vloženie do DB

node scripts/encrypt-password.js 'your-password'

Spustenie

Prvý setup

  1. Nainštaluj dependencies

    npm install
    
  2. Skopíruj a nastav .env

    cp .env.example .env
    
    • Nastav DB_* credentials (default sú pre docker-compose)
    • Vygeneruj silný JWT_SECRET a JWT_REFRESH_SECRET
    • Vygeneruj 32-znakový ENCRYPTION_KEY (pre šifrovanie JMAP hesiel)
    • Nastav CORS_ORIGIN pre frontend (default: http://localhost:5173)
  3. Spusti PostgreSQL databázu

    docker-compose up -d postgres
    
  4. Aplikuj databázové migrácie

    npm run db:migrate
    
  5. Vytvor admin účet

    npm run db:seed
    

    ⚠️ DÔLEŽITÉ: Skopíruj si vygenerované temporary heslo! Budeš ho potrebovať pri prvom prihlásení.

  6. Spusti server

    npm run dev
    
  7. API beží na http://localhost:5000

    • Health check: GET /health
    • API docs: Všetky endpointy sú popísané v sekcii "API Endpointy"

Každodenný development

# Spusti databázu (ak nie je spustená)
docker-compose up -d postgres

# Spusti dev server
npm run dev

# Otvor DB GUI (voliteľné)
npm run db:studio

Ako to funguje

Architektúra

Aplikácia používa layered architecture so separáciou zodpovedností:

Client Request
    ↓
Routes (routing)
    ↓
Middlewares (auth, validation, rate limiting)
    ↓
Controllers (request handling, response formatting)
    ↓
Services (business logic)
    ↓
Database (Drizzle ORM)

Flow autentifikácie a onboardingu

  1. Admin vytvorí nového usera

    • POST /api/admin/users s username, firstName, lastName, role
    • Systém vygeneruje náhodné temporary heslo (16 znakov, mix uppercase/lowercase/numbers/symbols)
    • Heslo sa hashuje bcryptom (12 rounds) a uloží do temp_password
    • changed_password = false
  2. Prvé prihlásenie

    • User sa prihlási s temporary heslom: POST /api/auth/login
    • Backend zistí že changed_password = false a vráti flag mustChangePassword: true
    • Frontend redirectne na "set password" screen
  3. Nastavenie vlastného hesla

    • POST /api/auth/set-password s novým heslom
    • Validácia: min 8 znakov, uppercase, lowercase, number, symbol
    • Heslo sa hashuje a uloží do password fieldu
    • temp_password = null, changed_password = true
  4. Session management

    • Pri login dostane user JWT access token (httpOnly cookie, 1h)
    • Refresh token (httpOnly cookie, 7 dní)
    • Pri expirácii access tokenu sa automaticky refreshne

Email synchronizácia flow

  1. Pripojenie email účtu

    • User pridá JMAP účet: POST /api/email-accounts
    • Backend overí JMAP credentials volaním getJmapSession()
    • Heslo sa zašifruje AES-256-GCM a uloží do DB
    • JMAP accountId sa uloží pre budúce requesty
  2. Prvý sync

    • Automaticky sa stiahnu emaily z INBOX
    • Email/query + Email/get JMAP volania
    • Emaily sa uložia do DB s thread_id pre organizáciu konverzácií
  3. Nepretržitý sync

    • Frontend pravidelne volá GET /api/emails?accountId=X
    • Backend volá JMAP a stiahne nové emaily od posledného syncu
    • Update-uje is_read status podľa JMAP

Kontakty a auto-sync

  1. Discovery kontaktov

    • GET /api/contacts/discover?accountId=X
    • Backend stiahne všetky emaily z JMAP
    • Extrahuje unikátne email adresy z from a to polí
    • Vráti zoznam emailov ktoré ešte nie sú v kontaktoch
  2. Pridanie kontaktu

    • POST /api/contacts s email a emailAccountId
    • Backend uloží kontakt do DB
    • Auto-sync: Automaticky vyhľadá všetky emaily od/pre tento kontakt cez JMAP
    • Stiahnuť a uloží všetky nájdené emaily s linknutím na kontakt (contact_id)
  3. Email thread organizácia

    • Emaily sa zoskupujú podľa thread_id (z JMAP)
    • GET /api/emails/thread/:threadId vráti chronologickú konverzáciu
    • Mark as read označí všetky emaily v threade

Bezpečnostné mechanizmy

Rate Limiting:

  • Login: 5 pokusov / 15 min (brute force ochrana)
  • API: 100 requestov / 15 min (1000 v dev mode)
  • Sensitive operations: 3 pokusy / 15 min

Password Security:

  • Bcrypt hashing s 12 rounds (2^12 = 4096 iterations)
  • Temporary passwords: 16 znakov, vysoká entropia
  • Validácia: min 8 znakov, mix typov znakov

Data Encryption:

  • JMAP heslá: AES-256-GCM (symetrické šifrovanie)
  • Format: iv:authTag:encryptedText
  • Kľúč derivovaný z ENCRYPTION_KEY cez scrypt

Session Security:

  • JWT tokeny v httpOnly cookies (XSS ochrana)
  • SameSite=Strict (CSRF ochrana)
  • Krátka platnosť access tokenu (1h)
  • Refresh token rotation

Input Validation:

  • Zod schemas pre všetky endpointy
  • XSS sanitizácia cez xss-clean
  • SQL injection ochrana cez Drizzle ORM prepared statements

Audit Logging:

  • Všetky dôležité akcie (login, password change, user creation, email account add/remove)
  • Ukladá user_id, action, resource, old/new values, IP, user-agent
  • GET /api/admin/audit-logs pre adminov

Database Cascade Deletes

User Delete:

  • Cascade vymaže: email_accounts → contacts → emails → audit_logs

Email Account Delete:

  • Cascade vymaže: contacts → emails (pre tento účet)
  • User si môže pridať ďalší účet

Contact Delete:

  • Emaily od tohto kontaktu zostávajú (len contact_id = null)
  • Možnosť filtrovať "orphaned" emaily

JMAP Operácie

Supported operations:

  1. Email/query - Vyhľadávanie emailov

    {
      filter: { inMailbox: 'inbox' },
      sort: [{ property: 'receivedAt', isAscending: false }],
      limit: 50
    }
    
  2. Email/get - Získanie detailov emailov

    {
      ids: ['id1', 'id2'],
      properties: ['from', 'to', 'subject', 'bodyValues', 'threadId', ...]
    }
    
  3. Email/set - Vytvorenie emailu (draft)

    {
      create: {
        draft1: {
          mailboxIds: { drafts: true },
          from: [...], to: [...],
          subject: '...', bodyValues: { body: { value: '...' }}
        }
      }
    }
    
  4. EmailSubmission/set - Poslanie emailu

    {
      create: {
        sub1: {
          emailId: 'draft1',
          identityId: 'identity1'
        }
      }
    }
    
  5. Email/changes - Incremental sync (delta updates)

    • Používa sinceState pre získanie len zmenených emailov
    • Optimalizované pre veľké mailboxy

Šifrovanie JMAP hesiel

Encryption flow:

// Encryption (pri pridaní účtu)
1. Vygeneruj náhodný IV (16 bytes)
2. Vytvor cipher s AES-256-GCM, key, IV
3. Zašifruj heslo
4. Získaj auth tag
5. Ulož: `${iv}:${authTag}:${encrypted}`

// Decryption (pri JMAP operáciách)
1. Split stored value na [iv, authTag, encrypted]
2. Vytvor decipher s AES-256-GCM, key, IV
3. Nastav auth tag
4. Dešifruj heslo
5. Použij pre JMAP request

Multi-Account Management

Každý user môže mať viacero email účtov:

  • Jeden je označený ako primárny (is_primary = true)
  • Kontakty a emaily sú izolované per účet (accountId filter)
  • Frontend prepína medzi účtami cez accountId parameter
  • Každý účet má vlastný JMAP session a credentials

Error Handling

Centrálny error handler middleware:

  • Všetky chyby idú cez errorHandler.js
  • Custom error classes: BadRequestError, UnauthorizedError, NotFoundError, ConflictError
  • Production mode: Skryje stack traces
  • Development mode: Full error details + stack trace
  • Všetky errory sa logujú cez Winston logger

Systém rolí

Admin

  • Všetko čo Member
  • /api/admin/* endpointy
  • Vytvorenie/zmazanie používateľov
  • Zmena rolí

Member

  • Vlastný profil a nastavenia
  • Správa vlastných email účtov
  • Vlastné kontakty a emaily
  • Inbox

JMAP Integrácia

Provider: Truemail.sk

JMAP Endpoint: https://mail.truemail.sk/jmap/

Autentifikácia: Basic Auth

  • Username: email adresa (napr. user@slovensko.ai)
  • Password: email heslo (uložené encrypted v DB)

JMAP Session

Každý JMAP request začína získaním session:

GET https://mail.truemail.sk/jmap/session/
Authorization: Basic base64(email:password)

Response:
{
  "capabilities": {
    "urn:ietf:params:jmap:core": { maxObjectsInGet: 500, ... },
    "urn:ietf:params:jmap:mail": { ... }
  },
  "accounts": {
    "account-id": {
      "name": "user@slovensko.ai",
      "isPersonal": true,
      "accountCapabilities": { ... }
    }
  },
  "primaryAccounts": {
    "urn:ietf:params:jmap:mail": "account-id"
  }
}

accountId sa ukladá do DB (jmap_account_id) a používa pre všetky ďalšie requesty.

Supported JMAP Methods

1. Email/query - Vyhľadávanie emailov

[
  "Email/query",
  {
    accountId: "account-id",
    filter: {
      inMailbox: "inbox",      // alebo "sent", "drafts"
      from: "email@domain.sk"  // voliteľný filter
    },
    sort: [{ property: "receivedAt", isAscending: false }],
    limit: 50,
    position: 0
  },
  "call-id"
]

Response: { list: ["emailId1", "emailId2", ...], total: 156 }

2. Email/get - Získanie detailov

[
  "Email/get",
  {
    accountId: "account-id",
    ids: ["emailId1", "emailId2"],
    properties: [
      "id", "threadId", "mailboxIds", "keywords",
      "from", "to", "cc", "bcc",
      "subject", "receivedAt", "bodyValues",
      "textBody", "htmlBody"
    ],
    bodyProperties: ["partId", "type", "value"]
  },
  "call-id"
]

Response: {
  list: [{
    id: "emailId1",
    from: [{ email: "sender@domain.sk", name: "Sender Name" }],
    subject: "Email subject",
    bodyValues: { body: { value: "Email content..." } },
    ...
  }]
}

3. Email/set - Vytvorenie/Update/Delete

// Vytvorenie draft emailu
[
  "Email/set",
  {
    accountId: "account-id",
    create: {
      "draft-1": {
        mailboxIds: { "drafts-mailbox-id": true },
        from: [{ email: "me@slovensko.ai" }],
        to: [{ email: "recipient@domain.sk" }],
        subject: "Reply subject",
        bodyValues: {
          body: {
            value: "Email content",
            type: "text/plain"
          }
        },
        textBody: [{ partId: "body", type: "text/plain" }],
        keywords: { "$draft": true }
      }
    }
  },
  "call-id"
]

// Update (napr. mark as read)
[
  "Email/set",
  {
    accountId: "account-id",
    update: {
      "emailId1": {
        "keywords/$seen": true    // mark as read
      }
    }
  },
  "call-id"
]

4. EmailSubmission/set - Poslanie emailu

[
  "EmailSubmission/set",
  {
    accountId: "account-id",
    create: {
      "submission-1": {
        emailId: "draft-1",           // ID z Email/set create
        identityId: "identity-id",    // Z Identity/get
        envelope: {
          mailFrom: { email: "me@slovensko.ai" },
          rcptTo: [{ email: "recipient@domain.sk" }]
        }
      }
    }
  },
  "call-id"
]

5. Mailbox/get - Zoznam mailboxov (INBOX, Sent, Drafts, ...)

[
  "Mailbox/get",
  {
    accountId: "account-id",
    ids: null  // null = všetky
  },
  "call-id"
]

Response: {
  list: [
    { id: "inbox-id", name: "Inbox", role: "inbox", ... },
    { id: "sent-id", name: "Sent", role: "sent", ... }
  ]
}

6. Identity/get - Email identity (pre sending)

[
  "Identity/get",
  {
    accountId: "account-id",
    ids: null
  },
  "call-id"
]

Response: {
  list: [{
    id: "identity-id",
    email: "me@slovensko.ai",
    name: "My Name"
  }]
}

7. Email/changes - Delta sync (incremental updates)

[
  "Email/changes",
  {
    accountId: "account-id",
    sinceState: "previous-state-token",
    maxChanges: 100
  },
  "call-id"
]

Response: {
  oldState: "previous-state",
  newState: "current-state",
  hasMoreChanges: false,
  created: ["emailId1"],
  updated: ["emailId2"],
  destroyed: ["emailId3"]
}

JMAP Request Format

Všetky requesty používajú rovnaký formát:

POST https://mail.truemail.sk/jmap/api/
Authorization: Basic base64(email:password)
Content-Type: application/json

{
  "using": [
    "urn:ietf:params:jmap:core",
    "urn:ietf:params:jmap:mail"
  ],
  "methodCalls": [
    ["Method/name", { params }, "call-id"],
    ...
  ]
}

Error Handling

JMAP errory majú formát:

{
  "methodResponses": [
    ["error", {
      "type": "invalidArguments",
      "description": "Invalid filter"
    }, "call-id"]
  ]
}

Common error types:

  • invalidArguments - Zlé parametre
  • accountNotFound - Neplatný accountId
  • notFound - Email/mailbox nenájdený
  • forbidden - Nedostatočné oprávnenia
  • serverFail - Server error

Optimalizácie

Batching:

  • Jeden HTTP request môže obsahovať viacero method calls
  • Príklad: Email/query + Email/get v jednom requeste

Result References:

  • Výsledok jedného method callu môže byť použitý v ďalšom
  • Príklad: Email/query → Email/get s #ids referenciou

Incremental Sync:

  • Používaj Email/changes namiesto full Email/query
  • Ukladaj state token pre ďalšie syncs
  • Znižuje bandwidth a load

Šifrovanie

JMAP heslá - AES-256-GCM

  • Format: iv:authTag:encryptedText
  • Kľúč: ENCRYPTION_KEY z .env (32 znakov)
  • Funkcie: encryptPassword(), decryptPassword()

User heslá - Bcrypt

  • 12 rounds (2^12 iterations)
  • Funkcie: hashPassword(), comparePassword()
Description
No description provided
Readme 5.5 MiB
Languages
JavaScript 92%
HTML 7.9%
Dockerfile 0.1%