Eviworx
Docs

Settings API

The Settings API manages the general settings (company name, application URL), numbering, the email, Microsoft Teams and Webex connections, the CAPTCHA configuration and the enabled languages. It also reports the status of the notification channels.

⚙️
Features
✓ Numbering per object type (prefix + digit count)
✓ Company name and application URL
✓ Branding (name, logo, favicon, colors)
✓ Email connection (SMTP/IMAP/Graph API)
✓ Teams and Webex bot with connection test
✓ Turnstile CAPTCHA (bot protection)
✓ 5 selectable languages (DE, EN, ES, FR, IT)
✓ Secrets never in GET (_has* flag only)
✓ Separate permissions per settings category
✓ Audit log of every change

Authentication, Permissions & Structure

Each settings key has a read and a write permission. Holding either one allows reading: the write permission includes reading so that the form shows the stored values when editing and saving does not replace them with defaults. PUT /api/settings/:key expects the value as { "value": … } and validates it against the schema of the key (e.g. numbering).

  • User-only: All settings endpoints require a logged-in user; API keys are rejected. The exceptions are the public GETs /captcha and /enabled-languages.
  • settings.viewGeneral is intended for administrators and is not part of the End User and Agent system roles. general-settings and ui-settings (branding, locale) can be read by any logged-in user.
  • Sensitive keys: entra-id-config, webex-settings and teams-settings are only reachable through their own endpoints (see Integration Settings), which never return secrets in plain text.
  • Further endpoints: /api/settings/license (product license) and /api/settings/file-settings (Attachments) are documented on the linked pages.

System currency & price mode: general-settings contains systemCurrency (single currency for all amounts, default EUR, no conversion) and priceTaxMode (net | gross, default net; labels price fields, no tax calculation). Both apply system-wide to assets, contracts, licenses, cost centers and reports. A change takes effect in the backend immediately; the worker containers pick it up within 60 seconds.

Global Search

Cross-entity search (GET /api/search) is its own domain and has its own page: Global Search →.

Numbering Settings

Entity Number Formats

Entity Format Example Reset Policy
TicketPREFIX-NNNNNNTKT-000001Never
ProblemPREFIX-NNNNNNPRB-000001Never
ChangePREFIX-NNNNNNCHG-000001Never
IncidentPREFIX-YYYY-NNNNNNINC-2026-000001Yearly

Numbering Settings Endpoints

Method Endpoint Description
GET/PUT/api/settings/:keyNumbering for tickets, problems, changes and incidents (key = ticket-numbering-settings, problem-numbering-settings, change-numbering-settings, incident-numbering-settings). PUT expects { "value": {…} } and validates the value against the schema of the key.

System & Languages

Method Endpoint Description
GET/api/settings/captchaTurnstile CAPTCHA configuration (public)
GET/api/settings/enabled-languagesEnabled languages (public)
PUT/api/settings/enabled-languagesConfigure enabled languages
GET/api/settings/channel-statusNotification channel status (email, Teams, Webex)
GET/api/settings/system-bannerSystem banner message

General Settings: Company name (companyName) and application URL (applicationUrl) are configured via PUT /api/settings/general-settings. Both values are used for QR codes, PDF labels and email templates. The same key carries the system defaults for language (defaultLanguage), timezone (timezone, default Europe/Berlin) and date format (dateTimeFormat, default dd/MM/yyyy HH:mm). They apply to every user without an own preference — in the interface as well as in the texts the server generates (email, push, Webex, Teams). Setting timezone and date format explicitly during setup is recommended so that both sides show the same picture.

Numbering Configuration

// GET Response
GET /api/settings/ticket-numbering-settings

Response:
{
  "prefix": "TKT",              // 1-10 uppercase letters
  "suffixLength": 6,            // 1-10 digits (zero-padded)
  "lastAssignedNumber": 12345  // read-only: last number handed out (null = none yet)
}

// Generated Ticket Number:
// TKT-012345 (prefix + zero-padded atomic counter)

Update Numbering

// Custom numbering for tickets
const update = await fetch('/api/settings/ticket-numbering-settings', {
  method: 'PUT',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    value: {
      prefix: "TICKET",    // Custom prefix (only prefix + suffixLength are settable)
      suffixLength: 4      // Shorter suffix
    }
  })
});

const result = await update.json();
console.log(result);
// {
//   "prefix": "TICKET",
//   "suffixLength": 4,
//   "lastAssignedNumber": null   // read-only; the atomic counter keeps numbers unique
// }

// Next generated ticket number continues from the atomic counter:
// e.g. TICKET-2175, TICKET-2176, ...

⚠️ Warning: Numbering settings should be configured BEFORE production start. Changes after first tickets may lead to confusing numbers.

Year-Based Numbering (Incidents)

// Incidents have year-based counters
// Counter key: "incident-number-{YEAR}"

// 2025:
INC-2025-000001
INC-2025-000002
...
INC-2025-012345

// 2026 (automatic reset):
INC-2026-000001
INC-2026-000002
...

// Advantage: easy filtering by year

Application Settings

Settings Endpoints

Method Endpoint Description
GET/api/settingsAll settings in category general
GET/api/settings/:keyGet specific setting
PUT/api/settings/:keyUpdate setting
DELETE/api/settings/:keyDelete setting

UI Settings (Application Branding)

// Get UI settings
GET /api/settings/ui-settings

Response:
{
  "applicationName": "ACME IT Helpdesk",
  "logo": {
    "url": "/uploads/logo.png",
    "width": 200,
    "height": 60
  },
  "favicon": {
    "url": "/uploads/favicon.ico"
  },
  "theme": {
    "primaryColor": "#3b82f6",
    "accentColor": "#8b5cf6"
  },
  "branding": {
    "companyName": "ACME Corporation",
    "supportEmail": "support@acme.com",
    "supportPhone": "+1 555 1234567"
  }
}

// Update UI settings
PUT /api/settings/ui-settings
{
  "value": {
    "applicationName": "New Helpdesk Name",
    "logo": {
      "url": "/uploads/new-logo.png"
    }
  }
}

Language Settings

// Available languages (PUBLIC endpoint)
GET /api/settings/enabled-languages

Response:
{
  "languages": ["de", "en"]
}

// Update language settings (Admin)
PUT /api/settings/enabled-languages
{
  "languages": ["de", "en", "fr"]
}
// The effective default language must stay in the list —
// otherwise 400 DEFAULT_LANGUAGE_NOT_ENABLED

Integration Settings

Email Settings

Method Endpoint Description
GET/api/settings/emailEmail settings (SMTP/Graph; secrets only as _has* flag)
POST/api/settings/emailUpdate email settings
POST/api/settings/email/test-smtpTest SMTP connection
POST/api/settings/email/test-graphTest Microsoft Graph API connection
// Update email settings
POST /api/settings/email
{
  "isEnabled": true,
  "smtp": {
    "enabled": true,
    "host": "smtp.gmail.com",
    "port": 587,
    "security": "tls",
    "username": "notifications@company.com",
    "password": "app-specific-password",
    "fromAddress": "notifications@company.com",
    "fromName": "IT Helpdesk",
    "tlsVerify": true
  }
}

// Test SMTP connection
POST /api/settings/email/test-smtp

Response:
{
  "connected": true,
  "diagnostic": null   // optional technical diagnostic from the email worker
}
// Failure: 400 EMAIL_CONNECTION_TEST_FAILED

Teams Settings

Method Endpoint Description
GET/api/settings/teamsTeams Bot Framework settings
POST/api/settings/teamsUpdate Teams settings
POST/api/settings/teams/testTest Teams Bot connection
POST/api/teams/botTeams Bot Framework messaging endpoint (called by Microsoft)
// Teams Bot Framework konfigurieren
POST /api/settings/teams
{
  "appId": "00000000-0000-0000-0000-000000000000",  // Azure App Registration (GUID)
  "appPassword": "your-bot-secret",
  "tenantId": "your-tenant-id",
  "isEnabled": true
}

// Test senden
POST /api/settings/teams/test

Response:
{
  "connected": true,
  "connectedUsers": 12,
  "connectedChannels": 2,
  "testMessageSent": true
}

Webex Settings

Method Endpoint Description
GET/api/settings/webexWebex bot settings (token only as _hasToken flag)
POST/api/settings/webexUpdate Webex settings
POST/api/settings/webex/testTest Webex bot connection
// Webex Bot konfigurieren
POST /api/settings/webex
{
  "botToken": "Bearer_YOUR_BOT_TOKEN_HERE",
  "isEnabled": true
}

// Bot-Connection testen
POST /api/settings/webex/test

Response:
{
  "connected": true,
  "botId": "webex-bot-id",
  "botName": "Helpdesk Bot",
  "botEmail": "bot@webex.bot"
}

Settings Categories & Permissions

Category Settings Keys Permissions
Email /api/settings/email (own endpoint) settings.viewEmail, settings.editEmail
Integrations webex-settings, teams-settings, entra-id-config (own endpoints; secrets only as _has* flag) settings.viewIntegrations, settings.editIntegrations
Numbering ticket/problem/change/incident-numbering-settings settings.viewNumbering, settings.editNumbering
Security captcha/turnstile-settings settings.editSecurity
SLA sla-settings settings.editSLA (read AND write)
General general-settings, ui-settings (readable by any logged-in user) settings.viewGeneral (for administrators), settings.editGeneral

SLA thresholds (sla-settings)

PUT /api/settings/sla-settings
{
  "value": {
    "warningThresholdPercent": 80,     // 50–99
    "criticalThresholdMinutes": 60     // 5–1440
  }
}

When an SLA counts as WARNING and when a breach escalates to CRITICAL. sla-settings belongs to category sla and is therefore not included in GET /api/settings; both reading and writing require settings.editSLA so that the SLA thresholds are not shown to every holder of settings.viewGeneral. Details and cache behavior: SLA Management API.

Security Features

Secret Masking

// GET Response maskiert Secrets
GET /api/settings/webex

Response:
{
  "isEnabled": true,
  "_hasToken": true          // Secret never returned — only this boolean flag
}

// GET response for SMTP
{
  "smtp": {
    "username": "notifications@company.com",
    "_hasPassword": true      // Secret never returned — only this boolean flag
  }
}

Secrets are never returned on GET — only a _has* flag indicates whether a value is set. In addition, the SMTP password, the MS-Graph and Entra clientSecret, the Webex botToken and the Teams appPassword are stored encrypted with AES-256-GCM. Details on the security page.

RBAC Integration

  • Critical settings: every change checks the permission directly in the database, bypassing the cache; a revoked right takes effect immediately

SSRF Protection

Teams bot communication only accepts service URLs on approved Microsoft domains over HTTPS. The list of domains is documented under Integrations →.

Notification Channel Status

Channel Status Endpoint

// Get status of all notification channels
GET /api/settings/channel-status

Response:
{
  "EMAIL":  { "enabled": true,  "configured": true },
  "TEAMS":  { "enabled": true,  "configured": true },
  "WEBEX":  { "enabled": false, "configured": false },
  "IN_APP": { "enabled": true,  "configured": true },
  "PUSH":   { "enabled": true,  "configured": true }
}

Best Practices

  1. Numbering Setup: Configure BEFORE production start, use meaningful prefixes
  2. Suffix Length: 6 digits for large deployments (up to 999,999), 4 for small
  3. Email Test: Always run test-smtp/test-graph after settings change
  4. Channel Status: After changes, use channel-status to check that all channels are enabled and configured
  5. UI Branding: Logo max. 200x60px, favicon 32x32px for best display
  6. Secrets: Use strong passwords, rotate tokens regularly
  7. Language Support: Enable only languages with complete templates
  8. Permissions: Only ADMIN should have settings.editIntegrations (critical)

Related Documentation