-- Migration 017: Password reset tokens -- Progetto allineamento NIS2 ↔ TRPG — Fase 3 / G08 -- Data: 2026-05-29 -- -- Tabella per supportare il flusso "Password dimenticata": -- 1. POST /auth/forgot-password { email } → genera token, salva hash, invia mail -- 2. POST /auth/reset-password { token, new_password } → verifica + setta nuova pwd -- -- TTL: 30 min (decisione utente §10.4) -- Single-use: `used_at` viene settato al consumo -- Rate limit: 3 richieste/h per IP+email (applicato in controller) -- -- Rollback: DROP TABLE password_reset_tokens; SET @tbl := ( SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'password_reset_tokens' ); SET @sql := IF(@tbl = 0, 'CREATE TABLE password_reset_tokens ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, token_hash CHAR(64) NOT NULL UNIQUE COMMENT ''SHA-256 hex del token in chiaro inviato via mail'', expires_at TIMESTAMP NOT NULL COMMENT ''Default 30 min dopo created_at'', used_at TIMESTAMP NULL COMMENT ''Settato al primo consumo — token diventa single-use'', ip_address VARCHAR(45) NULL COMMENT ''IP del richiedente forgot-password'', created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, INDEX idx_token (token_hash), INDEX idx_expires (expires_at), INDEX idx_user_unused (user_id, used_at, expires_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT=''Token reset password — TTL 30min single-use''', 'SELECT ''password_reset_tokens già presente — skip'' AS info' ); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT TABLE_NAME, ENGINE, TABLE_COMMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'password_reset_tokens';