diff --git a/database/migrations/000_initial_schema_v1.1.0.sql b/database/migrations/000_initial_schema_v1.1.0.sql index a08eb76..4903a2c 100644 --- a/database/migrations/000_initial_schema_v1.1.0.sql +++ b/database/migrations/000_initial_schema_v1.1.0.sql @@ -89,6 +89,10 @@ CREATE TABLE IF NOT EXISTS users ( email_verified BOOLEAN DEFAULT FALSE, email_verification_token VARCHAR(255) NULL, email_verification_sent_at TIMESTAMP NULL, + two_factor_enabled BOOLEAN DEFAULT FALSE, + two_factor_secret VARCHAR(32) NULL, + two_factor_backup_codes TEXT NULL, + two_factor_setup_at TIMESTAMP NULL, full_name VARCHAR(255), role VARCHAR(50) DEFAULT 'user', is_active BOOLEAN DEFAULT TRUE, @@ -156,6 +160,34 @@ CREATE TABLE IF NOT EXISTS remember_tokens ( INDEX idx_expires_at (expires_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- Two-factor authentication verification attempts table +CREATE TABLE IF NOT EXISTS two_factor_verification_attempts ( + id INT AUTO_INCREMENT PRIMARY KEY, + user_id INT NOT NULL, + ip_address VARCHAR(45) NOT NULL, + success BOOLEAN DEFAULT FALSE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, + INDEX idx_user_id (user_id), + INDEX idx_ip_address (ip_address), + INDEX idx_created_at (created_at) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- Two-factor authentication email codes table +CREATE TABLE IF NOT EXISTS two_factor_email_codes ( + id INT AUTO_INCREMENT PRIMARY KEY, + user_id INT NOT NULL, + code VARCHAR(6) NOT NULL, + expires_at TIMESTAMP NOT NULL, + used BOOLEAN DEFAULT FALSE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, + INDEX idx_user_id (user_id), + INDEX idx_code (code), + INDEX idx_expires_at (expires_at), + INDEX idx_used (used) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + -- User notifications table (in-app notifications) CREATE TABLE IF NOT EXISTS user_notifications ( id INT AUTO_INCREMENT PRIMARY KEY, @@ -175,6 +207,55 @@ CREATE TABLE IF NOT EXISTS user_notifications ( INDEX idx_type (type) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +-- Error logs table for debugging and error tracking +CREATE TABLE IF NOT EXISTS error_logs ( + id INT PRIMARY KEY AUTO_INCREMENT, + error_id VARCHAR(32) UNIQUE NOT NULL COMMENT 'Unique reference ID for user reporting', + error_type VARCHAR(100) NOT NULL COMMENT 'Exception class name', + error_message TEXT NOT NULL COMMENT 'Error message', + error_file VARCHAR(500) NOT NULL COMMENT 'File where error occurred', + error_line INT NOT NULL COMMENT 'Line number where error occurred', + stack_trace TEXT COMMENT 'Full stack trace', + + -- Request context + request_method VARCHAR(10) COMMENT 'HTTP method (GET, POST, etc)', + request_uri VARCHAR(500) COMMENT 'Request URI', + request_data TEXT COMMENT 'JSON encoded POST/GET data (sanitized)', + + -- User context + user_id INT NULL COMMENT 'User who encountered the error', + user_agent TEXT COMMENT 'Browser user agent string', + ip_address VARCHAR(45) COMMENT 'IP address (IPv4 or IPv6)', + session_data TEXT COMMENT 'Session data (sanitized, no passwords)', + + -- System context + php_version VARCHAR(20) COMMENT 'PHP version at time of error', + memory_usage BIGINT COMMENT 'Memory usage in bytes', + + -- Tracking + occurred_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'First occurrence timestamp', + occurrences INT DEFAULT 1 COMMENT 'Number of times this error occurred', + last_occurred_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Last occurrence timestamp', + + -- Management + is_resolved BOOLEAN DEFAULT FALSE COMMENT 'Admin marked as resolved', + resolved_at TIMESTAMP NULL COMMENT 'When marked as resolved', + resolved_by INT NULL COMMENT 'Admin user who resolved it', + notes TEXT COMMENT 'Admin notes about resolution', + + -- Foreign keys + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL, + FOREIGN KEY (resolved_by) REFERENCES users(id) ON DELETE SET NULL, + + -- Indexes for performance + KEY idx_error_id (error_id), + KEY idx_error_type (error_type), + KEY idx_occurred_at (occurred_at), + KEY idx_user_id (user_id), + KEY idx_is_resolved (is_resolved), + KEY idx_occurrences (occurrences) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + -- ===================================================== -- TLD REGISTRY SYSTEM -- ===================================================== @@ -264,6 +345,11 @@ INSERT INTO settings (setting_key, setting_value, `type`, `description`) VALUES ('captcha_secret_key', '', 'encrypted', 'CAPTCHA secret key (encrypted)'), ('recaptcha_v3_score_threshold', '0.5', 'string', 'reCAPTCHA v3 minimum score threshold (0.0 to 1.0)'), +-- Two-factor authentication settings +('two_factor_policy', 'optional', 'string', '2FA policy: disabled, optional, or required'), +('two_factor_rate_limit_minutes', '15', 'string', 'Rate limit for 2FA attempts in minutes'), +('two_factor_email_code_expiry_minutes', '10', 'string', 'Email code expiry time in minutes'), + -- User isolation settings ('user_isolation_mode', 'shared', 'string', 'User data visibility mode: shared (all users see all data) or isolated (users see only their own data)')