feat: version 2.7.0 -- menu Contraseñas (repositorio de credenciales privado)

Nuevo modulo backend/src/modules/vault/: contraseña y notas cifradas
en el servidor (AES-256-GCM, mismo mecanismo ya usado para la clave
SMTP). Acceso al menu protegido con un PIN de 4 digitos independiente
del login (token corto propio, header X-Vault-Token, nunca el JWT de
sesion). El PIN no participa del cifrado -- cambiarlo o restablecerlo
por correo nunca afecta las contraseñas ya guardadas. Privado por
usuario, sin excepcion. Cada accion sensible (crear/editar/eliminar/
revelar/desbloquear) queda en audit_log. Compartir con otro usuario
queda para una proxima version.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-10-01 12:12:54 -05:00
parent f607455668
commit 0be0712ff0
20 changed files with 879 additions and 10 deletions
+10
View File
@@ -40,6 +40,7 @@
| `audit_log` | auditoría central (quién, qué, sobre qué, cuándo) |
| `error_logs` | errores de backend (excepciones 500) y frontend (JS/promesas sin catch), panel "Errores del sistema" en Configuración |
| `notes` | apuntes rápidos personales, siempre privados de cada usuario, menú propio "Notas" |
| `vault_entries` | repositorio de credenciales privado por usuario (menú "Contraseñas"), contraseña/notas cifradas |
## Relaciones clave
@@ -118,6 +119,15 @@
del todo desde el panel ("Limpiar registro"). `severity` (alta/media/baja) nunca se etiqueta a
mano: backend y errores de render de React = alta, errores JS sueltos = media, promesas
rechazadas sin manejar = baja.
- `vault_entries` (desde v2.7.0): `password_enc`/`notes_enc` guardan el resultado de `encrypt()`
(AES-256-GCM, `backend/src/utils/crypto.js`, mismo mecanismo ya usado para la clave SMTP) —
nunca texto plano. Privado por usuario, sin excepción (ni superadmin ve lo de otro). El acceso
al menú "Contraseñas" además pide un PIN de 4 dígitos (`users.vault_pin_hash`, bcrypt) — el PIN
es un candado de acceso, NO participa del cifrado (sería débil para eso). Cambiar/resetear el
PIN (incluso por correo, `vault_pin_reset_token`) nunca toca `vault_entries` — es un cambio de
candado, no una recuperación de datos. Cada vez que se revela/crea/edita/elimina una entrada, o
se desbloquea el candado, queda en `audit_log`. Compartir una entrada con otro usuario queda
para una fase 2 (no implementado).
## Riesgos o decisiones