DKIM rotation broke the domain it was run on. It retired the live key and inserted a placeholder as ACTIVE - private_key_enc was the literal string "dummy-encrypted-key" - so FindActiveKeys then failed for the whole domain and outbound mail stopped being signed, with the real key already gone. Reproduced against a database before changing anything. The root cause runs deeper: the auth service derives its encryption key with a plain SHA-256 of the master key while the protocols service uses HKDF with its own info string, so nothing the auth service seals can ever be opened by the signer. Rotation therefore moves to the protocols service, which owns that vault and the real key generator. It retires the previous key with a seven-day overlap in the same transaction rather than deleting it, because mail already sent under it is still being verified. Domain onboarding had three defects in one function. It built the alias destination by interpolating the domain name into the SQL text, which was injectable; it reused one placeholder for a CITEXT and a VARCHAR column, which made the statement fail and happened to hide the injection; and it ignored its scope argument entirely, so any DOMAIN_ADMIN could create domains. It also provisioned postmaster, abuse and security, missing the dmarc and tlsrpt aliases that the published records point at - PLAN.md section 7.4b is explicit that reports bounce without them. The TLS panel returned fixed values: acme_status "VALID" and 72 days to expiry, whatever the process actually held. It now reads the certificate watcher, and a compile-time assertion keeps the wiring from silently regressing into "disabled". The audit log and the readiness scorecard were fixtures too, and their field names did not match the API they now read. Two tests failed and a third asserted a fabricated constant: one depended on test order through a shared fixture that had a second factor enrolled, one used a fixed domain name and so passed once per database, and one expected "records: 13" from a function that never touches DNS. All three are fixed, and the suite now passes twice in a row against one database. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
148 lines
5.8 KiB
JSON
148 lines
5.8 KiB
JSON
{
|
|
"common": {
|
|
"appName": "LambdaMail",
|
|
"userPortal": "Webmail",
|
|
"adminPortal": "Consola de Gestión",
|
|
"loading": "Cargando...",
|
|
"save": "Guardar Cambios",
|
|
"cancel": "Cancelar",
|
|
"delete": "Eliminar",
|
|
"confirm": "Confirmar",
|
|
"search": "Buscar",
|
|
"status": "Estado",
|
|
"actions": "Acciones",
|
|
"refresh": "Actualizar",
|
|
"logout": "Cerrar Sesión"
|
|
},
|
|
"auth": {
|
|
"userLoginTitle": "Iniciar Sesión en Webmail",
|
|
"adminLoginTitle": "Iniciar Sesión en Consola Admin",
|
|
"emailLabel": "Dirección de Correo",
|
|
"passwordLabel": "Contraseña",
|
|
"signInButton": "Iniciar Sesión",
|
|
"totpCodeLabel": "Código del Autenticador (6 dígitos)",
|
|
"verifyCodeButton": "Verificar Código",
|
|
"invalidCredentials": "Correo o contraseña no válidos",
|
|
"mfaRequired": "Código de autenticación de dos factores requerido"
|
|
},
|
|
"mail": {
|
|
"inbox": "Bandeja de Entrada",
|
|
"sent": "Enviados",
|
|
"drafts": "Borradores",
|
|
"trash": "Papelera",
|
|
"junk": "Spam",
|
|
"archive": "Archivo",
|
|
"compose": "Redactar Correo",
|
|
"noMessages": "No hay mensajes en esta carpeta",
|
|
"unreadCount": "{count, plural, =0 {Sin mensajes no leídos} one {# mensaje no leído} other {# mensajes no leídos}}",
|
|
"loadImages": "Cargar Imágenes Remotas",
|
|
"reply": "Responder",
|
|
"forward": "Reenviar",
|
|
"undoSend": "Deshacer Envío ({seconds}s restantes)"
|
|
},
|
|
"settings": {
|
|
"title": "Configuración de la Cuenta",
|
|
"security": "Seguridad y 2FA",
|
|
"appPasswords": "Contraseñas de Aplicación",
|
|
"sessions": "Sesiones Activas",
|
|
"mfaStatus": "Estado de Autenticación de Dos Factores",
|
|
"mfaEnabled": "2FA está Activo",
|
|
"mfaDisabled": "2FA está Desactivado",
|
|
"enableMfa": "Activar 2FA",
|
|
"generateAppPassword": "Generar Contraseña de Aplicación",
|
|
"recoveryCodesTitle": "Códigos de Recuperación",
|
|
"saveRecoveryCodes": "Guarde estos códigos de recuperación en un lugar seguro. No se volverán a mostrar.",
|
|
"language": "Idioma",
|
|
"signOut": "Cerrar sesión",
|
|
"langEn": "Inglés",
|
|
"langPtBR": "Portugués (Brasil)",
|
|
"langEs": "Español"
|
|
},
|
|
"admin": {
|
|
"dashboardTitle": "Panel del Sistema",
|
|
"domainsTitle": "Dominios y DNS (13 Registros)",
|
|
"mailboxesTitle": "Buzones y Cuentas",
|
|
"aliasesTitle": "Alias y Enrutamiento",
|
|
"queueTitle": "Cola de Entrega de Salida",
|
|
"dmarcTitle": "Análisis DMARC",
|
|
"securityTitle": "Seguridad y Registro de Auditoría",
|
|
"preflightTitle": "Diagnóstico Preflight",
|
|
"reconcileDns": "Reconciliar Registros DNS",
|
|
"dnsStatusVerified": "VERIFICADO",
|
|
"dnsStatusDrift": "DESVÍO DETECTADO",
|
|
"dnsStatusPartial": "PARCIAL",
|
|
"retryJob": "Reintentar Entrega",
|
|
"cancelJob": "Cancelar Trabajo",
|
|
"freezeDomain": "Congelar Destino"
|
|
},
|
|
"errors": {
|
|
"unauthorized": "Sesión expirada o no autorizada",
|
|
"forbidden": "Acceso prohibido para esta superficie de cuenta",
|
|
"serverError": "Ocurrió un error interno en el servidor"
|
|
},
|
|
"ui": {
|
|
"accountStatus": "Estado de la cuenta",
|
|
"actions": "Acciones",
|
|
"active": "ACTIVA",
|
|
"activeSessions": "Sesiones activas del webmail",
|
|
"actor": "Autor / cuenta",
|
|
"actualRecord": "Registro DNS actual (Cloudflare)",
|
|
"allChecksPassed": "TODAS LAS COMPROBACIONES PASARON",
|
|
"appPasswordGenerated": "Contrasena de aplicacion generada:",
|
|
"appPasswordsSection": "Contrasenas de aplicacion (clientes IMAP / SMTP)",
|
|
"attempts": "Intentos",
|
|
"clientIp": "IP del cliente",
|
|
"copyPasswordNow": "Copie esta contrasena ahora. No se mostrara de nuevo.",
|
|
"coreInfra": "Estado de la infraestructura",
|
|
"currentSession": "Sesion actual de este navegador",
|
|
"daneVerified": "DANE / MTA-STS verificado",
|
|
"destination": "Destino",
|
|
"diskUsed": "Uso de disco",
|
|
"dkimResult": "Resultado DKIM",
|
|
"dkimAlignment": "Alineacion de la firma DKIM",
|
|
"dmarcEnforcement": "Aplicacion de la politica DMARC",
|
|
"domainVerification": "Estado de la verificacion del dominio",
|
|
"emailAddress": "Direccion de correo",
|
|
"eventAction": "Accion registrada",
|
|
"expectedValue": "Valor esperado por la especificacion",
|
|
"healthy": "SALUDABLE",
|
|
"imapEngine": "Servidor IMAP (143/993)",
|
|
"inboundVolume": "Volumen de entrada (24h)",
|
|
"jobId": "ID del trabajo",
|
|
"lastError": "Ultimo error",
|
|
"liveMetrics": "Metricas operativas del nodo de correo.",
|
|
"localDisk": "Almacenamiento en disco local",
|
|
"preflightTitle": "Diagnostico de preflight del servidor",
|
|
"messageBody": "Cuerpo del mensaje",
|
|
"messageVolume": "Volumen de mensajes",
|
|
"noAppPasswords": "Aun no se generaron contrasenas de aplicacion.",
|
|
"online": "EN LINEA",
|
|
"outboundDelivered": "Entregados en salida (24h)",
|
|
"queueDepth": "Profundidad de la cola",
|
|
"postgresRunner": "Ejecutor de tareas Postgres activo",
|
|
"provisionMailbox": "Crear nuevo buzon",
|
|
"recipient": "Destinatario",
|
|
"recordName": "Nombre del registro",
|
|
"reportingOrg": "Organizacion que informo",
|
|
"scanners": "Rspamd (antispam) y ClamAV",
|
|
"sender": "Remitente",
|
|
"smtpListener": "Servidor SMTP (25/587/465)",
|
|
"sourceIp": "IP de origen",
|
|
"spfRatio": "Tasa de alineacion SPF",
|
|
"spfResult": "Resultado SPF",
|
|
"storageQuota": "Cuota de almacenamiento",
|
|
"subject": "Asunto",
|
|
"targetObject": "Objeto destino",
|
|
"timestamp": "Fecha y hora",
|
|
"toRecipients": "Para (destinatarios)",
|
|
"totalEvaluated": "Total de mensajes evaluados",
|
|
"twoFactorSection": "Autenticacion en dos pasos (TOTP RFC 6238)",
|
|
"watching": "OBSERVANDO",
|
|
"passwordChanged": "Contrasena cambiada",
|
|
"signOutOthers": "Cerrar las otras sesiones",
|
|
"changePassword": "Cambiar contrasena",
|
|
"currentPassword": "Contrasena actual",
|
|
"newPassword": "Nueva contrasena (min. 12 caracteres)"
|
|
}
|
|
}
|