-- Fase 1 security hardening migration. -- Run against an existing database (using the original -- giandonatoinverso/php-dynamic-qr-code-db image or an older init.sql). -- Columns/tables are only added if they don't already exist. SET @db := DATABASE(); SET @col_exists := ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'users' AND COLUMN_NAME = 'must_change_password' ); SET @sql := IF(@col_exists = 0, 'ALTER TABLE `users` ADD COLUMN `must_change_password` TINYINT(1) NOT NULL DEFAULT 0', 'SELECT 1'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET @col_exists := ( SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'users' AND COLUMN_NAME = 'password_changed_at' ); SET @sql := IF(@col_exists = 0, 'ALTER TABLE `users` ADD COLUMN `password_changed_at` DATETIME DEFAULT NULL', 'SELECT 1'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- An existing superadmin account with the factory password (superadmin/superadmin) -- must change its password on next login. UPDATE `users` SET `must_change_password` = 1 WHERE `username` = 'superadmin' AND `password` = '$2y$10$xpZc5KC.aU2XHkcqhuZGFuAnqmtL4Unt8MysOyylceq.19XIyoZpG'; CREATE TABLE IF NOT EXISTS `login_attempts` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `ip_address` varchar(45) NOT NULL, `success` tinyint(1) NOT NULL DEFAULT 0, `attempted_at` datetime NOT NULL, PRIMARY KEY (`id`), KEY `username_attempted_at` (`username`, `attempted_at`), KEY `ip_attempted_at` (`ip_address`, `attempted_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `audit_log` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `user_id` int(25) DEFAULT NULL, `username` varchar(50) DEFAULT NULL, `action` varchar(50) NOT NULL, `target_type` varchar(30) DEFAULT NULL, `target_id` varchar(50) DEFAULT NULL, `ip_address` varchar(45) DEFAULT NULL, `user_agent` varchar(255) DEFAULT NULL, `created_at` datetime NOT NULL, PRIMARY KEY (`id`), KEY `created_at` (`created_at`), KEY `user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;