feat: version 4.6.0 -- Cambio de correo con aprobacion

El usuario solicita el cambio desde Mi cuenta (correo nuevo + clave actual). Lo
aprueba un admin/superadmin (colaboradores), solo un superadmin (admins) o el propio
superadmin mediante enlace a su correo actual. Tras aprobar se envia confirmacion al
correo nuevo y aviso al actual; al confirmar se aplica el cambio y se cierran todas
las sesiones. Todo el proceso queda en auditoria. Migracion 035.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Milton Gonzalez
2026-10-28 12:03:23 -05:00
parent d562351242
commit bdc62403f4
25 changed files with 449 additions and 6 deletions
@@ -0,0 +1,28 @@
CREATE TABLE IF NOT EXISTS email_change_requests (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
old_email VARCHAR(160) NOT NULL,
new_email VARCHAR(160) NOT NULL,
status ENUM('pending','approved','rejected','cancelled','expired','applied','failed') NOT NULL DEFAULT 'pending',
requires_self_approval TINYINT(1) NOT NULL DEFAULT 0,
approve_token_hash CHAR(64) NULL,
approve_token_expires DATETIME NULL,
confirm_token_hash CHAR(64) NULL,
confirm_token_expires DATETIME NULL,
decided_by INT NULL,
decided_at DATETIME NULL,
reject_reason VARCHAR(1000) NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
applied_at DATETIME NULL,
open_user_id INT AS (CASE WHEN status IN ('pending','approved') THEN user_id ELSE NULL END) PERSISTENT,
open_new_email VARCHAR(160) AS (CASE WHEN status IN ('pending','approved') THEN new_email ELSE NULL END) PERSISTENT,
UNIQUE KEY uq_email_change_open_user (open_user_id),
UNIQUE KEY uq_email_change_open_email (open_new_email),
INDEX idx_email_change_user_status (user_id, status),
INDEX idx_email_change_approve_hash (approve_token_hash),
INDEX idx_email_change_confirm_hash (confirm_token_hash),
CONSTRAINT fk_email_change_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_email_change_decider FOREIGN KEY (decided_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE notifications MODIFY COLUMN entity_type ENUM('project','activity','meeting','email_change_request') NULL;