-- ============================================================================ -- MIGRATION: Phase 1 Security & Stability Database Schema Updates -- Date: 2025-12-03 -- Description: Add tables and columns required for Phase 1 security features -- (login rate limiting, account lockout, audit logging) -- ============================================================================ -- Track failed login attempts for rate limiting and account lockout CREATE TABLE IF NOT EXISTS login_attempts ( attempt_id BIGINT PRIMARY KEY AUTO_INCREMENT, email VARCHAR(255) NOT NULL, ip_address VARCHAR(45) NOT NULL, attempted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, success BOOLEAN DEFAULT FALSE, INDEX idx_email_ip (email, ip_address), INDEX idx_attempted_at (attempted_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- Add account lockout column to users table -- Stores the timestamp until which the account is locked -- NULL = account not locked, Future datetime = account locked until this time ALTER TABLE users ADD COLUMN locked_until DATETIME NULL DEFAULT NULL AFTER is_verified; CREATE INDEX idx_locked_until ON users (locked_until); -- Security audit log for sensitive operations DROP TABLE IF EXISTS `audit_log`; CREATE TABLE IF NOT EXISTS audit_log ( log_id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id INT NULL, action VARCHAR(100) NOT NULL COMMENT 'e.g., LOGIN, FAILED_LOGIN, ACCOUNT_LOCKED, FILE_UPLOAD', resource_type VARCHAR(50) COMMENT 'e.g., users, bookings, payments', resource_id INT COMMENT 'ID of affected resource', ip_address VARCHAR(45) NOT NULL, user_agent TEXT NULL, details TEXT COMMENT 'JSON or text details about the action', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_user_id (user_id), INDEX idx_action (action), INDEX idx_created_at (created_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ============================================================================ -- ROLLBACK INSTRUCTIONS (if needed) -- ============================================================================ -- ALTER TABLE users DROP COLUMN locked_until; -- DROP TABLE IF EXISTS login_attempts; -- DROP TABLE IF EXISTS audit_log;