Файловый менеджер - Редактировать - /home/gqdcvggs/go.imators.com/TwoFactorAuth.php.tar
Назад
home/gqdcvggs/idsma.imators.com/TwoFactorAuth.php 0000664 00000015006 15114742073 0016103 0 ustar 00 <?php require_once 'vendor/autoload.php'; require_once 'db.php'; use PragmaRX\Google2FA\Google2FA; use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\Image\SvgImageBackEnd; use BaconQrCode\Renderer\RendererStyle\RendererStyle; use BaconQrCode\Writer; class TwoFactorAuth { private $db; private $google2fa; private const BACKUP_CODES_COUNT = 8; private const MAX_ATTEMPTS = 5; private const LOCKOUT_TIME = 900; public function __construct(Database $db) { $this->db = $db->connect(); $this->google2fa = new Google2FA(); } public function setupTwoFactor($userId, $email) { try { $secretKey = $this->google2fa->generateSecretKey(); $backupCodes = $this->generateBackupCodes(); $stmt = $this->db->prepare("SELECT id FROM two_factor_auth WHERE user_id = ?"); $stmt->execute([$userId]); $exists = $stmt->fetch(); if ($exists) { $stmt = $this->db->prepare(" UPDATE two_factor_auth SET secret_key = ?, backup_codes = ?, is_enabled = FALSE WHERE user_id = ? "); } else { $stmt = $this->db->prepare(" INSERT INTO two_factor_auth (user_id, secret_key, backup_codes, is_enabled) VALUES (?, ?, ?, FALSE) "); } $stmt->execute([ $exists ? $secretKey : $userId, json_encode($backupCodes), $exists ? $userId : $secretKey ]); $qrCodeUrl = $this->google2fa->getQRCodeUrl( 'Imators Auth', $email, $secretKey ); $renderer = new ImageRenderer( new RendererStyle(400), new SvgImageBackEnd() ); $writer = new Writer($renderer); return [ 'success' => true, 'secret' => $secretKey, 'qrCode' => $writer->writeString($qrCodeUrl), 'backupCodes' => $backupCodes ]; } catch (PDOException $e) { error_log("2FA Setup Error: " . $e->getMessage()); return ['success' => false, 'error' => 'Setup error']; } } public function verifyCode($userId, $code) { try { $stmt = $this->db->prepare(" SELECT secret_key, backup_codes, attempt_count, last_attempt FROM two_factor_auth WHERE user_id = ? AND is_enabled = TRUE "); $stmt->execute([$userId]); $auth = $stmt->fetch(PDO::FETCH_ASSOC); if (!$auth) return false; if ($this->isLocked($auth['attempt_count'], $auth['last_attempt'])) { throw new Exception("Account temporarily locked"); } $isValid = false; if (strlen($code) === 6) { $isValid = $this->google2fa->verifyKey($auth['secret_key'], $code); } elseif (strlen($code) === 8) { $backupCodes = json_decode($auth['backup_codes'], true); if (in_array($code, $backupCodes)) { $backupCodes = array_diff($backupCodes, [$code]); $this->updateBackupCodes($userId, $backupCodes); $isValid = true; } } if ($isValid) { $this->resetAttempts($userId); return ['success' => true]; } else { $this->incrementAttempts($userId); return ['success' => false, 'error' => 'Invalid code']; } } catch (Exception $e) { return ['success' => false, 'error' => $e->getMessage()]; } } public function enableTwoFactor($userId, $code) { try { $stmt = $this->db->prepare("SELECT * FROM two_factor_auth WHERE user_id = ?"); $stmt->execute([$userId]); $result = $stmt->fetch(PDO::FETCH_ASSOC); error_log("Attempting to verify code: " . $code . " with secret: " . $result['secret_key']); // Important: Le window period doit être large pour la vérification initiale if (!$result || !$this->google2fa->verify($code, $result['secret_key'], null, 8)) { error_log("Verification failed for user " . $userId); return ['success' => false, 'error' => 'Invalid code']; } $stmt = $this->db->prepare(" UPDATE two_factor_auth SET is_enabled = TRUE, updated_at = CURRENT_TIMESTAMP WHERE user_id = ? "); $stmt->execute([$userId]); error_log("2FA enabled successfully for user " . $userId); return ['success' => true]; } catch (Exception $e) { error_log("Enable 2FA Error: " . $e->getMessage()); return ['success' => false, 'error' => $e->getMessage()]; } } private function generateBackupCodes() { $codes = []; for ($i = 0; $i < self::BACKUP_CODES_COUNT; $i++) { $codes[] = strtoupper(bin2hex(random_bytes(4))); } return $codes; } private function isLocked($attemptCount, $lastAttempt) { if ($attemptCount >= self::MAX_ATTEMPTS) { $lockoutEnd = strtotime($lastAttempt) + self::LOCKOUT_TIME; return time() < $lockoutEnd; } return false; } private function resetAttempts($userId) { $stmt = $this->db->prepare(" UPDATE two_factor_auth SET attempt_count = 0, last_attempt = NULL WHERE user_id = ? "); $stmt->execute([$userId]); } private function incrementAttempts($userId) { $stmt = $this->db->prepare(" UPDATE two_factor_auth SET attempt_count = attempt_count + 1, last_attempt = CURRENT_TIMESTAMP WHERE user_id = ? "); $stmt->execute([$userId]); } private function updateBackupCodes($userId, $codes) { $stmt = $this->db->prepare(" UPDATE two_factor_auth SET backup_codes = ? WHERE user_id = ? "); $stmt->execute([json_encode(array_values($codes)), $userId]); } } home/gqdcvggs/.trash/TwoFactorAuth.php 0000664 00000015006 15114746205 0013754 0 ustar 00 <?php require_once 'vendor/autoload.php'; require_once 'db.php'; use PragmaRX\Google2FA\Google2FA; use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\Image\SvgImageBackEnd; use BaconQrCode\Renderer\RendererStyle\RendererStyle; use BaconQrCode\Writer; class TwoFactorAuth { private $db; private $google2fa; private const BACKUP_CODES_COUNT = 8; private const MAX_ATTEMPTS = 5; private const LOCKOUT_TIME = 900; public function __construct(Database $db) { $this->db = $db->connect(); $this->google2fa = new Google2FA(); } public function setupTwoFactor($userId, $email) { try { $secretKey = $this->google2fa->generateSecretKey(); $backupCodes = $this->generateBackupCodes(); $stmt = $this->db->prepare("SELECT id FROM two_factor_auth WHERE user_id = ?"); $stmt->execute([$userId]); $exists = $stmt->fetch(); if ($exists) { $stmt = $this->db->prepare(" UPDATE two_factor_auth SET secret_key = ?, backup_codes = ?, is_enabled = FALSE WHERE user_id = ? "); } else { $stmt = $this->db->prepare(" INSERT INTO two_factor_auth (user_id, secret_key, backup_codes, is_enabled) VALUES (?, ?, ?, FALSE) "); } $stmt->execute([ $exists ? $secretKey : $userId, json_encode($backupCodes), $exists ? $userId : $secretKey ]); $qrCodeUrl = $this->google2fa->getQRCodeUrl( 'Imators Auth', $email, $secretKey ); $renderer = new ImageRenderer( new RendererStyle(400), new SvgImageBackEnd() ); $writer = new Writer($renderer); return [ 'success' => true, 'secret' => $secretKey, 'qrCode' => $writer->writeString($qrCodeUrl), 'backupCodes' => $backupCodes ]; } catch (PDOException $e) { error_log("2FA Setup Error: " . $e->getMessage()); return ['success' => false, 'error' => 'Setup error']; } } public function verifyCode($userId, $code) { try { $stmt = $this->db->prepare(" SELECT secret_key, backup_codes, attempt_count, last_attempt FROM two_factor_auth WHERE user_id = ? AND is_enabled = TRUE "); $stmt->execute([$userId]); $auth = $stmt->fetch(PDO::FETCH_ASSOC); if (!$auth) return false; if ($this->isLocked($auth['attempt_count'], $auth['last_attempt'])) { throw new Exception("Account temporarily locked"); } $isValid = false; if (strlen($code) === 6) { $isValid = $this->google2fa->verifyKey($auth['secret_key'], $code); } elseif (strlen($code) === 8) { $backupCodes = json_decode($auth['backup_codes'], true); if (in_array($code, $backupCodes)) { $backupCodes = array_diff($backupCodes, [$code]); $this->updateBackupCodes($userId, $backupCodes); $isValid = true; } } if ($isValid) { $this->resetAttempts($userId); return ['success' => true]; } else { $this->incrementAttempts($userId); return ['success' => false, 'error' => 'Invalid code']; } } catch (Exception $e) { return ['success' => false, 'error' => $e->getMessage()]; } } public function enableTwoFactor($userId, $code) { try { $stmt = $this->db->prepare("SELECT * FROM two_factor_auth WHERE user_id = ?"); $stmt->execute([$userId]); $result = $stmt->fetch(PDO::FETCH_ASSOC); error_log("Attempting to verify code: " . $code . " with secret: " . $result['secret_key']); // Important: Le window period doit être large pour la vérification initiale if (!$result || !$this->google2fa->verify($code, $result['secret_key'], null, 8)) { error_log("Verification failed for user " . $userId); return ['success' => false, 'error' => 'Invalid code']; } $stmt = $this->db->prepare(" UPDATE two_factor_auth SET is_enabled = TRUE, updated_at = CURRENT_TIMESTAMP WHERE user_id = ? "); $stmt->execute([$userId]); error_log("2FA enabled successfully for user " . $userId); return ['success' => true]; } catch (Exception $e) { error_log("Enable 2FA Error: " . $e->getMessage()); return ['success' => false, 'error' => $e->getMessage()]; } } private function generateBackupCodes() { $codes = []; for ($i = 0; $i < self::BACKUP_CODES_COUNT; $i++) { $codes[] = strtoupper(bin2hex(random_bytes(4))); } return $codes; } private function isLocked($attemptCount, $lastAttempt) { if ($attemptCount >= self::MAX_ATTEMPTS) { $lockoutEnd = strtotime($lastAttempt) + self::LOCKOUT_TIME; return time() < $lockoutEnd; } return false; } private function resetAttempts($userId) { $stmt = $this->db->prepare(" UPDATE two_factor_auth SET attempt_count = 0, last_attempt = NULL WHERE user_id = ? "); $stmt->execute([$userId]); } private function incrementAttempts($userId) { $stmt = $this->db->prepare(" UPDATE two_factor_auth SET attempt_count = attempt_count + 1, last_attempt = CURRENT_TIMESTAMP WHERE user_id = ? "); $stmt->execute([$userId]); } private function updateBackupCodes($userId, $codes) { $stmt = $this->db->prepare(" UPDATE two_factor_auth SET backup_codes = ? WHERE user_id = ? "); $stmt->execute([json_encode(array_values($codes)), $userId]); } }
| ver. 1.6 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка