{"openapi":"3.0.0","paths":{"/api/v1/email/send":{"post":{"operationId":"EmailController_send","summary":"Send a transactional email","description":"Uses the SMTP transport of the specified Client App (or central SMTP as fallback). **When `clientAppId` is provided, `fromAddress` is required** — each app must declare its own sender identity. System emails sent internally by the API use the central SMTP defaults from `.env` automatically.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailDto"}}}},"responses":{"200":{"description":"Email sent or failed with details."}},"tags":["Email as a Service"],"security":[{"bearer":[]}]}},"/api/v1/email/clients/{clientAppId}/configure-smtp":{"post":{"operationId":"EmailController_configureSmtp","summary":"Configure a custom SMTP server for a Client App (password stored encrypted)","description":"Saves the SMTP credentials for this app in the database (password encrypted AES-256-GCM). The `fromAddress` and `fromName` are **not** stored here — they must be specified in each `/email/send` request by the app.","parameters":[{"name":"clientAppId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigureSmtpDto"}}}},"responses":{"201":{"description":""}},"tags":["Email as a Service"],"security":[{"bearer":[]}]}},"/api/v1/email/queue":{"get":{"operationId":"EmailController_getQueue","summary":"List email queue history (all sent/failed emails)","parameters":[{"name":"status","required":false,"in":"query","schema":{"enum":["PENDING","SENT","FAILED"],"type":"string"}},{"name":"clientAppId","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Email as a Service"],"security":[{"bearer":[]}]}},"/api/v1/webhooks":{"post":{"operationId":"WebhookController_create","summary":"Register a new webhook for a Client App","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookDto"}}}},"responses":{"201":{"description":""}},"tags":["Webhooks"],"security":[{"bearer":[]}]}},"/api/v1/webhooks/client/{clientAppId}":{"get":{"operationId":"WebhookController_findByClientApp","summary":"List webhooks for a Client App","parameters":[{"name":"clientAppId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Webhooks"],"security":[{"bearer":[]}]}},"/api/v1/webhooks/{id}":{"patch":{"operationId":"WebhookController_update","summary":"Update a webhook configuration","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookDto"}}}},"responses":{"200":{"description":""}},"tags":["Webhooks"],"security":[{"bearer":[]}]},"delete":{"operationId":"WebhookController_delete","summary":"Delete a webhook","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Webhooks"],"security":[{"bearer":[]}]}},"/api/v1/auth/register":{"post":{"operationId":"AuthController_register","summary":"Register a new central user (sends verification email)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDto"}}}},"responses":{"201":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/login":{"post":{"operationId":"AuthController_login","summary":"Login — returns access/refresh tokens. MFA code required if enabled.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginDto"}}}},"responses":{"200":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/refresh":{"post":{"operationId":"AuthController_refresh","summary":"Rotate refresh token and get new access token","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenDto"}}}},"responses":{"200":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/verify":{"post":{"operationId":"AuthController_verify","summary":"Verify a JWT access token (for client microservices)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyTokenDto"}}}},"responses":{"200":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/verify-email":{"get":{"operationId":"AuthController_verifyEmail","summary":"Verify email address from token sent by email","parameters":[{"name":"token","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/resend-verification":{"post":{"operationId":"AuthController_resendVerification","summary":"Resend email verification link","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordDto"}}}},"responses":{"200":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/forgot-password":{"post":{"operationId":"AuthController_forgotPassword","summary":"Request password reset email","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordDto"}}}},"responses":{"200":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/reset-password":{"post":{"operationId":"AuthController_resetPassword","summary":"Reset password using token from email","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordDto"}}}},"responses":{"200":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/google":{"get":{"operationId":"AuthController_googleAuth","summary":"Redirect to Google OAuth login","parameters":[],"responses":{"200":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/google/callback":{"get":{"operationId":"AuthController_googleCallback","summary":"Google OAuth callback — issues tokens","parameters":[],"responses":{"200":{"description":""}},"tags":["Authentication & SSO"]}},"/api/v1/auth/me":{"get":{"operationId":"AuthController_getProfile","summary":"Get current authenticated user profile","parameters":[],"responses":{"200":{"description":""}},"tags":["Authentication & SSO"],"security":[{"bearer":[]}]}},"/api/v1/auth/logout":{"post":{"operationId":"AuthController_logout","summary":"Logout — blacklists current JWT and revokes all refresh tokens","parameters":[],"responses":{"200":{"description":""}},"tags":["Authentication & SSO"],"security":[{"bearer":[]}]}},"/api/v1/auth/change-password":{"post":{"operationId":"AuthController_changePassword","summary":"Change password (requires current password)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordDto"}}}},"responses":{"200":{"description":""}},"tags":["Authentication & SSO"],"security":[{"bearer":[]}]}},"/api/v1/auth/sessions":{"get":{"operationId":"AuthController_getSessions","summary":"List all active sessions for current user (with device & location)","parameters":[],"responses":{"200":{"description":""}},"tags":["Authentication & SSO"],"security":[{"bearer":[]}]},"delete":{"operationId":"AuthController_revokeAllSessions","summary":"Revoke ALL active sessions (logout everywhere)","parameters":[],"responses":{"200":{"description":""}},"tags":["Authentication & SSO"],"security":[{"bearer":[]}]}},"/api/v1/auth/sessions/{id}":{"delete":{"operationId":"AuthController_revokeSession","summary":"Revoke a specific session by ID","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Authentication & SSO"],"security":[{"bearer":[]}]}},"/api/v1/auth/mfa/status":{"get":{"operationId":"MfaController_getStatus","summary":"Get MFA status for current user","parameters":[],"responses":{"200":{"description":""}},"tags":["MFA — Multi-Factor Authentication"],"security":[{"bearer":[]}]}},"/api/v1/auth/mfa/setup":{"post":{"operationId":"MfaController_setup","summary":"Step 1: Generate TOTP secret and QR code to scan with authenticator app","parameters":[],"responses":{"201":{"description":"Returns secret, otpauthUrl and QR code data URL."}},"tags":["MFA — Multi-Factor Authentication"],"security":[{"bearer":[]}]}},"/api/v1/auth/mfa/enable":{"post":{"operationId":"MfaController_enable","summary":"Step 2: Confirm TOTP code to activate MFA — returns one-time recovery codes","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TotpCodeDto"}}}},"responses":{"200":{"description":"MFA enabled. Store recovery codes safely."}},"tags":["MFA — Multi-Factor Authentication"],"security":[{"bearer":[]}]}},"/api/v1/auth/mfa/disable":{"delete":{"operationId":"MfaController_disable","summary":"Disable MFA (requires current TOTP code)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TotpCodeDto"}}}},"responses":{"200":{"description":""}},"tags":["MFA — Multi-Factor Authentication"],"security":[{"bearer":[]}]}},"/api/v1/auth/mfa/verify-recovery":{"post":{"operationId":"MfaController_verifyRecovery","summary":"Use a recovery code instead of TOTP code","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecoveryCodeDto"}}}},"responses":{"200":{"description":""}},"tags":["MFA — Multi-Factor Authentication"],"security":[{"bearer":[]}]}},"/api/v1/users":{"post":{"operationId":"UsersController_create","summary":"Create a new user with web console or API-only permissions","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserDto"}}}},"responses":{"201":{"description":""}},"tags":["Users Management"],"security":[{"bearer":[]}]},"get":{"operationId":"UsersController_findAll","summary":"List all registered users","parameters":[],"responses":{"200":{"description":""}},"tags":["Users Management"],"security":[{"bearer":[]}]}},"/api/v1/users/{id}":{"delete":{"operationId":"UsersController_deleteUser","summary":"Delete a registered user by ID","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users Management"],"security":[{"bearer":[]}]},"get":{"operationId":"UsersController_findOne","summary":"Get user details and app roles by user ID","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users Management"],"security":[{"bearer":[]}]},"patch":{"operationId":"UsersController_update","summary":"Update user profile info or status","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":""}},"tags":["Users Management"],"security":[{"bearer":[]}]}},"/api/v1/users/{id}/roles":{"post":{"operationId":"UsersController_assignRole","summary":"Assign a role to a user for a specific Client App","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignRoleDto"}}}},"responses":{"201":{"description":""}},"tags":["Users Management"],"security":[{"bearer":[]}]}},"/api/v1/users/{id}/roles/{clientAppId}/{roleName}":{"delete":{"operationId":"UsersController_removeRole","summary":"Revoke a role from a user for a specific Client App","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"clientAppId","required":true,"in":"path","schema":{"type":"string"}},{"name":"roleName","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users Management"],"security":[{"bearer":[]}]}},"/api/v1/clients":{"post":{"operationId":"ClientsController_create","summary":"Register a new client application","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateClientDto"}}}},"responses":{"201":{"description":"Client application registered successfully."}},"tags":["Client Apps Management"],"security":[{"bearer":[]}]},"get":{"operationId":"ClientsController_findAll","summary":"List all registered client applications","parameters":[],"responses":{"200":{"description":""}},"tags":["Client Apps Management"],"security":[{"bearer":[]}]}},"/api/v1/clients/{id}":{"get":{"operationId":"ClientsController_findOne","summary":"Get details of a client application by ID or slug","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Client Apps Management"],"security":[{"bearer":[]}]},"patch":{"operationId":"ClientsController_update","summary":"Update client application settings","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateClientDto"}}}},"responses":{"200":{"description":""}},"tags":["Client Apps Management"],"security":[{"bearer":[]}]},"delete":{"operationId":"ClientsController_remove","summary":"Delete a client application","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Client Apps Management"],"security":[{"bearer":[]}]}},"/api/v1/clients/{id}/regenerate-secret":{"post":{"operationId":"ClientsController_regenerateSecret","summary":"Regenerate client app secret","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Client Apps Management"],"security":[{"bearer":[]}]}},"/api/v1/api-keys":{"post":{"operationId":"ApiKeysController_create","summary":"Issue a new API Key for M2M communication","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyDto"}}}},"responses":{"201":{"description":"API Key generated successfully."}},"tags":["API Keys (Server-to-Server M2M)"],"security":[{"bearer":[]}]}},"/api/v1/api-keys/client/{clientAppId}":{"get":{"operationId":"ApiKeysController_findByClientApp","summary":"List API keys for a specific Client App","parameters":[{"name":"clientAppId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["API Keys (Server-to-Server M2M)"],"security":[{"bearer":[]}]}},"/api/v1/api-keys/verify":{"post":{"operationId":"ApiKeysController_verify","summary":"Verify an API Key string","parameters":[],"responses":{"201":{"description":""}},"tags":["API Keys (Server-to-Server M2M)"]}},"/api/v1/api-keys/{id}":{"delete":{"operationId":"ApiKeysController_revoke","summary":"Revoke an API Key","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["API Keys (Server-to-Server M2M)"],"security":[{"bearer":[]}]}},"/api/v1/vault/secrets":{"post":{"operationId":"VaultController_setSecret","summary":"Store or update an encrypted secret","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetSecretDto"}}}},"responses":{"201":{"description":"Secret stored securely."}},"tags":["Credentials & Secrets Vault"],"security":[{"bearer":[]}]}},"/api/v1/vault/client/{clientAppId}":{"get":{"operationId":"VaultController_listSecrets","summary":"List secret names stored for a Client App","parameters":[{"name":"clientAppId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Credentials & Secrets Vault"],"security":[{"bearer":[]}]}},"/api/v1/vault/client/{clientAppId}/secret/{secretName}":{"get":{"operationId":"VaultController_getSecret","summary":"Decrypt and retrieve a specific secret value","parameters":[{"name":"clientAppId","required":true,"in":"path","schema":{"type":"string"}},{"name":"secretName","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Credentials & Secrets Vault"],"security":[{"bearer":[]}]},"delete":{"operationId":"VaultController_deleteSecret","summary":"Delete a stored secret","parameters":[{"name":"clientAppId","required":true,"in":"path","schema":{"type":"string"}},{"name":"secretName","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Credentials & Secrets Vault"],"security":[{"bearer":[]}]}},"/api/v1/audit":{"get":{"operationId":"AuditController_getAll","summary":"List all audit events (admin) — filterable by user, action, IP, date range","parameters":[{"name":"action","required":false,"in":"query","schema":{"enum":["USER_REGISTER","USER_LOGIN","USER_LOGIN_FAILED","USER_LOGOUT","USER_LOCKED","USER_UNLOCKED","USER_PASSWORD_CHANGED","USER_PASSWORD_RESET_REQUESTED","USER_PASSWORD_RESET","USER_EMAIL_VERIFICATION_SENT","USER_EMAIL_VERIFIED","USER_UPDATED","USER_DELETED","MFA_ENABLED","MFA_DISABLED","MFA_CHALLENGE_SUCCESS","MFA_CHALLENGE_FAILED","MFA_RECOVERY_USED","TOKEN_REFRESHED","TOKEN_REVOKED","TOKEN_BLACKLISTED","TOKEN_INTROSPECTED","CLIENT_APP_CREATED","CLIENT_APP_UPDATED","CLIENT_APP_DELETED","CLIENT_APP_SECRET_REGENERATED","API_KEY_CREATED","API_KEY_REVOKED","API_KEY_ROTATED","API_KEY_VERIFIED","VAULT_SECRET_SET","VAULT_SECRET_READ","VAULT_SECRET_DELETED","WEBHOOK_FIRED","EMAIL_SENT","ROLE_ASSIGNED","ROLE_REVOKED","LOGIN_NEW_DEVICE","LOGIN_NEW_LOCATION"],"type":"string"}},{"name":"userId","required":false,"in":"query","schema":{"type":"string"}},{"name":"ip","required":false,"in":"query","schema":{"type":"string"}},{"name":"from","required":false,"in":"query","description":"ISO date string","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"ISO date string","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Audit Logs & Security Events"],"security":[{"bearer":[]}]}},"/api/v1/audit/me":{"get":{"operationId":"AuditController_getMyLogs","summary":"Get audit log for the current authenticated user","parameters":[{"name":"offset","required":false,"in":"query","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Audit Logs & Security Events"],"security":[{"bearer":[]}]}},"/api/v1/audit/user/{userId}":{"get":{"operationId":"AuditController_getUserLogs","summary":"Get audit log for a specific user (admin)","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Audit Logs & Security Events"],"security":[{"bearer":[]}]}},"/api/v1/audit/client/{clientAppId}":{"get":{"operationId":"AuditController_getClientLogs","summary":"Get audit log for a specific Client App","parameters":[{"name":"clientAppId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Audit Logs & Security Events"],"security":[{"bearer":[]}]}},"/api/v1/admin/stats":{"get":{"operationId":"AdminController_getStats","summary":"Get aggregated system statistics for admin dashboard","parameters":[],"responses":{"200":{"description":""}},"tags":["Admin — Dashboard & Statistics"],"security":[{"bearer":[]}]}},"/api/v1/admin/users/locked":{"get":{"operationId":"AdminController_getLockedUsers","summary":"List currently locked user accounts","parameters":[],"responses":{"200":{"description":""}},"tags":["Admin — Dashboard & Statistics"],"security":[{"bearer":[]}]}},"/api/v1/admin/blacklist/stats":{"get":{"operationId":"AdminController_getBlacklistStats","summary":"Get JWT blacklist statistics","parameters":[],"responses":{"200":{"description":""}},"tags":["Admin — Dashboard & Statistics"],"security":[{"bearer":[]}]}},"/dashboard":{"get":{"operationId":"AdminViewController_getDashboardPage","summary":"Private Interactive Admin Console Dashboard UI","parameters":[],"responses":{"200":{"description":""}},"tags":["Admin — Dashboard & Statistics"]}},"/api/v1/health":{"get":{"operationId":"HealthController_check","summary":"Health check — DB status, uptime, version, environment","parameters":[],"responses":{"200":{"description":""}},"tags":["Health & Status"]}},"/docs":{"get":{"operationId":"DocsController_getDocsPage","summary":"Interactive Enterprise API Documentation UI","parameters":[],"responses":{"200":{"description":""}},"tags":["Documentation Portal"]}},"/installer/status":{"get":{"operationId":"InstallerController_getStatus","summary":"Check if system is already installed","parameters":[],"responses":{"200":{"description":""}},"tags":["System Setup & Installer"]}},"/installer/keys":{"get":{"operationId":"InstallerController_generateKeys","summary":"Generate random secure secrets for JWT and AES-256","parameters":[],"responses":{"200":{"description":""}},"tags":["System Setup & Installer"]}},"/api/v1/installer/test-db":{"post":{"operationId":"InstallerController_testDb","summary":"Test MySQL database credentials connectivity","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestDbDto"}}}},"responses":{"201":{"description":""}},"tags":["System Setup & Installer"]}},"/api/v1/installer/execute":{"post":{"operationId":"InstallerController_executeInstall","summary":"Execute full automated installation","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteInstallDto"}}}},"responses":{"201":{"description":""}},"tags":["System Setup & Installer"]}},"/install":{"get":{"operationId":"InstallerController_getInstallerPage","summary":"Interactive Web Setup Installer Wizard","parameters":[],"responses":{"200":{"description":""}},"tags":["System Setup & Installer"]}}},"info":{"title":"Api Zlp v2.0 — Central Identity & Credentials Service","description":"## 🔐 Servicio Central de Identidad y Credenciales\n\n### ⚡ Inicio Rápido\n\n**1. Registrar tu proyecto como Client App:**\n`POST /api/v1/clients` → Obtén tu `clientId` y `clientSecret`\n\n**2. Login de usuarios desde tu frontend:**\n`POST /api/v1/auth/login` → Retorna `accessToken` + `refreshToken` + geolocalización\n\n**3. Renovar el accessToken:**\n`POST /api/v1/auth/refresh` → Rotación automática del refresh token\n\n**4. Verificar un token desde tu backend:**\n`POST /api/v1/auth/verify` → Valida JWT y retorna el payload completo\n\n---\n\n### 🔑 Autenticación\nTodos los endpoints protegidos requieren: `Authorization: Bearer {accessToken}`\n\n---\n\n### 📧 Email — Regla del Sender\n- **Emails del sistema** (verificación, alertas, MFA): usan el SMTP y `from` del `.env` central.\n- **Emails de apps clientes** via `POST /email/send`: deben especificar `fromAddress` (y opcionalmente `fromName`) en cada request.\n\n---\n\n### 🌍 Geolocalización\nCada login, sesión y evento de audit incluye automáticamente:\n`ipAddress` · `country` · `city` · `region` · `latitude` · `longitude` · `deviceName` · `deviceType`","version":"2.0.0","contact":{}},"tags":[{"name":"Authentication & SSO","description":"Login, Register, Logout, Refresh, Verification, Google OAuth"},{"name":"MFA — Multi-Factor Authentication","description":"Google / Microsoft Authenticator TOTP setup & verification"},{"name":"Client Apps Management","description":"Manage client applications, origins, and IP rules"},{"name":"Users Management","description":"User profile, account status, and app-specific roles"},{"name":"API Keys (Server-to-Server M2M)","description":"Generate and manage server-to-server API keys"},{"name":"Credentials & Secrets Vault","description":"AES-256-GCM encrypted key-value vault for third-party secrets"},{"name":"Audit Logs & Security Events","description":"Security activity tracking with IP and geolocation data"},{"name":"Webhooks","description":"Real-time security event notifications with HMAC signatures"},{"name":"Email as a Service","description":"Transactional emails using custom or central SMTP"},{"name":"Admin — Dashboard & Statistics","description":"Aggregated analytics and security monitoring"},{"name":"Health & Status","description":"System health, uptime, and database latency"}],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SendEmailDto":{"type":"object","properties":{"to":{"type":"string","example":"user@example.com","description":"Recipient email address"},"toName":{"type":"string","example":"John Doe","description":"Recipient display name"},"subject":{"type":"string","example":"Welcome to our platform!"},"html":{"type":"string","example":"<h1>Hello</h1>","description":"HTML body content"},"text":{"type":"string","example":"Hello","description":"Plain-text fallback body"},"clientAppId":{"type":"string","example":"app-finance","description":"Client App ID or slug. Selects the SMTP transport for that app (falls back to central). When provided, fromAddress is required."},"fromName":{"type":"string","example":"Finance App","description":"Sender display name. Required when clientAppId is set — the system does not supply a default sender for client apps."},"fromAddress":{"type":"string","example":"noreply@finance-app.com","description":"Sender email address. Required when clientAppId is set — each app owns its own sender identity."}},"required":["to","subject","html"]},"ConfigureSmtpDto":{"type":"object","properties":{"smtpHost":{"type":"string","example":"mail.tudominio.com"},"smtpPort":{"type":"number","example":465,"description":"SMTP port. 465 = SSL, 587 = STARTTLS"},"smtpUser":{"type":"string","example":"noreply@tudominio.com"},"smtpPass":{"type":"string","example":"password_secreto","description":"Plain text SMTP password — stored AES-256-GCM encrypted in the database"}},"required":["smtpHost","smtpPort","smtpUser","smtpPass"]},"CreateWebhookDto":{"type":"object","properties":{"clientAppId":{"type":"string","example":"app-finance"},"name":{"type":"string","example":"Security Alerts Hook"},"url":{"type":"string","example":"https://myapp.com/webhooks/auth"},"events":{"example":["USER_LOGIN","MFA_ENABLED","USER_LOCKED"],"description":"Events to subscribe. Use [\"*\"] for all.","type":"array","items":{"type":"string"}},"secret":{"type":"string","example":"my-webhook-secret","description":"Optional HMAC secret for signature verification"}},"required":["clientAppId","name","url","events"]},"UpdateWebhookDto":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"}}},"RegisterDto":{"type":"object","properties":{"email":{"type":"string","example":"user@example.com","description":"User unique email address"},"password":{"type":"string","example":"StrongPassword123!","description":"Password (minimum 8 characters)"},"fullName":{"type":"string","example":"John Doe","description":"Full name of the user"}},"required":["email","password"]},"LoginDto":{"type":"object","properties":{"email":{"type":"string","example":"user@example.com"},"password":{"type":"string","example":"StrongPassword123!"},"clientId":{"type":"string","example":"app-finance","description":"Client App ID for role/scope assignment"},"clientSlug":{"type":"string","example":"admin-portal","description":"Client App slug"},"totpCode":{"type":"string","example":"123456","description":"6-digit TOTP code (required if MFA is enabled)"},"recoveryCode":{"type":"string","example":"ABCDE-FGHIJ","description":"MFA recovery code (alternative to totpCode)"}},"required":["email","password"]},"RefreshTokenDto":{"type":"object","properties":{"refreshToken":{"type":"string","description":"Valid refresh token string"}},"required":["refreshToken"]},"VerifyTokenDto":{"type":"object","properties":{"token":{"type":"string","description":"JWT access token to verify"}},"required":["token"]},"ForgotPasswordDto":{"type":"object","properties":{"email":{"type":"string","example":"user@example.com"}},"required":["email"]},"ResetPasswordDto":{"type":"object","properties":{"token":{"type":"string","example":"token-from-email"},"newPassword":{"type":"string","example":"NewPassword456!"}},"required":["token","newPassword"]},"ChangePasswordDto":{"type":"object","properties":{"currentPassword":{"type":"string","example":"OldPassword123!"},"newPassword":{"type":"string","example":"NewPassword456!"}},"required":["currentPassword","newPassword"]},"TotpCodeDto":{"type":"object","properties":{"code":{"type":"string","example":"123456","description":"6-digit TOTP code from authenticator app"}},"required":["code"]},"RecoveryCodeDto":{"type":"object","properties":{"recoveryCode":{"type":"string","example":"ABCDE-FGHIJ","description":"One-time recovery code"}},"required":["recoveryCode"]},"CreateUserDto":{"type":"object","properties":{"email":{"type":"string","example":"juan@empresa.com"},"fullName":{"type":"string","example":"Juan Pérez"},"password":{"type":"string","example":"Password123!"},"canAccessWebConsole":{"type":"boolean","example":true,"description":"Permitir acceso al Panel Web de la API (/dashboard)"}},"required":["email","fullName","password"]},"UpdateUserDto":{"type":"object","properties":{"fullName":{"type":"string","example":"Jane Doe"},"isActive":{"type":"boolean","example":true}}},"AssignRoleDto":{"type":"object","properties":{"clientAppId":{"type":"string","example":"app-finance"},"roleName":{"type":"string","example":"ADMIN"}}},"CreateClientDto":{"type":"object","properties":{"name":{"type":"string","example":"Finance Dashboard App","description":"Human readable name of the client app"},"slug":{"type":"string","example":"app-finance","description":"Unique slug identifier for the application"},"redirectUris":{"example":["http://localhost:3001/api/auth/callback"],"description":"Allowed redirect URIs","type":"array","items":{"type":"string"}},"allowedOrigins":{"example":["http://localhost:3001","https://finance.mycompany.com"],"description":"Allowed CORS origins","type":"array","items":{"type":"string"}}},"required":["name","slug"]},"UpdateClientDto":{"type":"object","properties":{"name":{"type":"string","example":"Updated App Name"},"redirectUris":{"example":["http://localhost:3001"],"type":"array","items":{"type":"string"}},"allowedOrigins":{"example":["http://localhost:3001"],"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean","example":true}}},"CreateApiKeyDto":{"type":"object","properties":{"clientAppId":{"type":"string","example":"app-finance","description":"Client App ID or Slug"},"name":{"type":"string","example":"Production Worker Service","description":"Name of the API key"},"scopes":{"example":["users:read","reports:generate"],"description":"Allowed scope permissions","type":"array","items":{"type":"string"}},"expiresAt":{"type":"string","example":"2026-12-31T23:59:59Z","description":"Optional expiration timestamp"}},"required":["clientAppId","name"]},"SetSecretDto":{"type":"object","properties":{"clientAppId":{"type":"string","example":"app-finance","description":"Client App ID or Slug"},"secretName":{"type":"string","example":"STRIPE_SECRET_KEY","description":"Secret identifier key"},"secretValue":{"type":"string","example":"sk_test_51Mz...","description":"Raw secret value to store securely"}},"required":["clientAppId","secretName","secretValue"]},"TestDbDto":{"type":"object","properties":{"dbType":{"type":"string","example":"mysql","description":"Database provider type (mysql)"},"dbHost":{"type":"string","example":"127.0.0.1","description":"Database host"},"dbPort":{"type":"number","example":3306,"description":"Database port"},"dbUser":{"type":"string","example":"root","description":"Database username"},"dbPassword":{"type":"string","example":"","description":"Database password"},"dbName":{"type":"string","example":"api_zlp","description":"Database name"}},"required":["dbType","dbHost","dbPort","dbUser","dbName"]},"ExecuteInstallDto":{"type":"object","properties":{"dbHost":{"type":"string","example":"127.0.0.1"},"dbPort":{"type":"number","example":3306},"dbUser":{"type":"string","example":"root"},"dbPassword":{"type":"string","example":""},"dbName":{"type":"string","example":"api_zlp"},"appPort":{"type":"number","example":3000},"appUrl":{"type":"string","example":"http://localhost:3000"},"jwtSecret":{"type":"string","example":"super_secret_jwt_key_32_chars_long"},"jwtRefreshSecret":{"type":"string","example":"super_secret_refresh_jwt_key_32_chars"},"encryptionKey":{"type":"string","example":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"},"adminName":{"type":"string","example":"Administrator"},"adminEmail":{"type":"string","example":"admin@zlp.local"},"adminPassword":{"type":"string","example":"Admin123456!"},"smtpHost":{"type":"string","example":"smtp.mailtrap.io"},"smtpPort":{"type":"number","example":587},"smtpUser":{"type":"string","example":"user"},"smtpPass":{"type":"string","example":"pass"},"smtpFrom":{"type":"string","example":"no-reply@zlp.local"},"domainName":{"type":"string","example":"api.midominio.com"},"setupSsl":{"type":"boolean","example":true},"sslEmail":{"type":"string","example":"admin@midominio.com"}},"required":["dbHost","dbPort","dbUser","dbName","appPort","appUrl","jwtSecret","jwtRefreshSecret","encryptionKey","adminName","adminEmail","adminPassword"]}}}}