Файловый менеджер - Редактировать - /home/gqdcvggs/idsma.imators.com/formore/index.php
Назад
<?php session_start(); require_once 'db.php'; require 'vendor/autoload.php'; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; use PHPMailer\PHPMailer\Exception; const MAX_ATTEMPTS = 3; const LOCKOUT_DURATION = 300; if(isset($_SESSION['user_id'])) { header('Location: https://idsma.imators.com/dashboard.php'); exit; } function getDeviceInfo($user_agent) { $device_info = [ 'device' => 'Unknown', 'os' => 'Unknown', 'browser' => 'Unknown' ]; if(preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i',$user_agent)) { $device_info['device'] = 'Mobile'; } elseif(preg_match('/tablet|ipad|playbook|silk/i', $user_agent)) { $device_info['device'] = 'Tablet'; } else { $device_info['device'] = 'Desktop'; } if(preg_match('/windows/i', $user_agent)) { $device_info['os'] = 'Windows'; } elseif(preg_match('/macintosh|mac os x/i', $user_agent)) { $device_info['os'] = 'MacOS / iOS'; } elseif(preg_match('/linux/i', $user_agent)) { $device_info['os'] = 'Linux'; } elseif(preg_match('/iphone|ipad|ipod/i', $user_agent)) { $device_info['os'] = 'iOS'; } elseif(preg_match('/android/i', $user_agent)) { $device_info['os'] = 'Android'; } if(preg_match('/MSIE|Trident/i', $user_agent)) { $device_info['browser'] = 'Internet Explorer'; } elseif(preg_match('/Firefox/i', $user_agent)) { $device_info['browser'] = 'Firefox'; } elseif(preg_match('/Chrome/i', $user_agent)) { $device_info['browser'] = 'Chrome'; } elseif(preg_match('/Safari/i', $user_agent)) { $device_info['browser'] = 'Safari'; } elseif(preg_match('/Opera|OPR/i', $user_agent)) { $device_info['browser'] = 'Opera'; } return $device_info; } function sendLoginNotification($email, $location, $device_info) { $mail = new PHPMailer(true); try { $mail->isSMTP(); $mail->Host = 'mail.imators.com'; $mail->SMTPAuth = true; $mail->Username = 'no-reply@imators.systems'; $mail->Password = 'imators.managements4455*#@'; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mail->Port = 587; $mail->SMTPOptions = [ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ] ]; $mail->setFrom('no-reply@imators.systems', 'Imators'); $mail->addAddress($email); $mail->addReplyTo('no-reply@imators.systems', 'No Reply'); $mail->isHTML(true); $mail->Subject = 'New Login to Your Imators Account'; $mail->Body = ' <div style="font-family: \'Poppins\', sans-serif; max-width: 600px; margin: 0 auto;"> <div style="background: #1a1a1a; padding: 30px; border-radius: 10px; color: white;"> <h1 style="margin-bottom: 20px;">We detected a new login to your account with the following details:</h1> <ul style="margin-bottom: 20px; list-style: none; padding: 0;"> <li style="margin-bottom: 5px;">Location: ' . ($location['location'] ?? 'Unknown') . '</li> <li style="margin-bottom: 5px;">Device: ' . $device_info['device'] . ' (' . $device_info['os'] . ')</li> <li style="margin-bottom: 5px;">Browser: ' . $device_info['browser'] . '</li> <li style="margin-bottom: 5px;">Time: ' . date('F j, Y g:i A') . '</li> </ul> <p style="margin-bottom: 30px;">If this wasn\'t you, please secure your account immediately.</p> <a href="https://idsma.imators.com" style="display: inline-block; background-color: #00ff00; color: black; padding: 10px 20px; text-decoration: none; border-radius: 5px;"> Go to Account Settings </a> <p style="margin-top: 20px; font-size: 12px; color: #888;"> If you believe someone has unauthorized access to your account, please contact our support team immediately. </p> </div> </div>'; $mail->send(); } catch (Exception $e) { error_log("Login email error: " . $mail->ErrorInfo); } } function logSuccessfulLogin($conn, $user, $location, $device_info) { $ip_address = $_SERVER['REMOTE_ADDR']; $watchguard_data = [ 'user_id' => $user['id'], 'ip-connected' => json_encode([ 'ip' => $ip_address, 'location' => $location['location'] ?? 'Unknown' ]), 'identified-screen' => json_encode($device_info), 'hours-of-connect' => date('H:i:s'), 'date-of-connect' => date('Y-m-d H:i:s') ]; $stmt = $conn->prepare(" INSERT INTO `connection-watchguard` (user_id, `ip-connected`, `identified-screen`, `hours-of-connect`, `date-of-connect`) VALUES (:user_id, :ip_connected, :identified_screen, :hours_of_connect, :date_of_connect) "); $stmt->execute([ ':user_id' => $watchguard_data['user_id'], ':ip_connected' => $watchguard_data['ip-connected'], ':identified_screen' => $watchguard_data['identified-screen'], ':hours_of_connect' => $watchguard_data['hours-of-connect'], ':date_of_connect' => $watchguard_data['date-of-connect'] ]); } $error = ''; $success = ''; $is_locked = false; $remaining_time = 0; $_SESSION['login_attempts'] ??= 0; if (isset($_SESSION['lockout_time']) && $_SESSION['lockout_time'] > time()) { $is_locked = true; $remaining_time = $_SESSION['lockout_time'] - time(); } if (isset($_GET['unlock']) && (!isset($_SESSION['lockout_time']) || $_SESSION['lockout_time'] <= time())) { unset($_SESSION['login_attempts']); unset($_SESSION['lockout_time']); $is_locked = false; } if(isset($_GET['verified'])) { $success = "Email verified! Please login to continue."; } if ($_SERVER['REQUEST_METHOD'] === 'POST' && !$is_locked) { $email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL); $password = $_POST['password']; try { $db = new Database(); $conn = $db->connect(); $stmt = $conn->prepare("SELECT * FROM utilisateurs WHERE email = ? AND is_verified = 1 LIMIT 1"); $stmt->execute([$email]); if($stmt->rowCount() > 0) { $user = $stmt->fetch(PDO::FETCH_ASSOC); if(password_verify($password, $user['password'])) { $stmt = $conn->prepare("SELECT passkey_enabled FROM utilisateurs WHERE id = ? LIMIT 1"); $stmt->execute([$user['id']]); $passkey_enabled = $stmt->fetchColumn(); if ($passkey_enabled) { $_SESSION['pending_passkey_auth'] = true; $_SESSION['pending_user_id'] = $user['id']; $_SESSION['pending_username'] = $user['username']; $_SESSION['pending_email'] = $user['email']; header('Location: https://idsma.imators.com/passkey.php'); exit; } unset($_SESSION['login_attempts']); unset($_SESSION['lockout_time']); $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; $device_info = getDeviceInfo($_SERVER['HTTP_USER_AGENT']); $ip_details = json_decode(file_get_contents("http://ip-api.com/json/" . $_SERVER['REMOTE_ADDR']), true); $location = []; if($ip_details && $ip_details['status'] === 'success') { $location = [ 'country' => $ip_details['country'], 'city' => $ip_details['city'], 'region' => $ip_details['regionName'], 'location' => "{$ip_details['city']}, {$ip_details['country']}" ]; } logSuccessfulLogin($conn, $user, $location, $device_info); sendLoginNotification($email, $location, $device_info); header('Location: https://idsma.imators.com/dashboard'); exit; } else { $_SESSION['login_attempts']++; if ($_SESSION['login_attempts'] >= MAX_ATTEMPTS) { $_SESSION['lockout_time'] = time() + LOCKOUT_DURATION; $is_locked = true; $error = "Too many failed attempts. Please wait 5 minutes."; } else { $error = "Invalid password"; } } } else { $error = "Email not found or not verified"; } } catch(PDOException $e) { $error = "Login failed: " . $e->getMessage(); } } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Imators Auth.</title> <meta name="description" content="Log in to your Imators account or create one to access a multitude of features that give you control over the system at your fingertips."> <meta property="og:url" content="https://accounts.imators.com"> <meta property="og:type" content="website"> <meta property="og:title" content="Imators Auth."> <meta property="og:description" content="Log in to your Imators account or create one to access a multitude of features that give you control over the system at your fingertips."> <meta property="og:image" content="https://opengraph.b-cdn.net/production/images/fb6bc1ea-5744-46f1-bee6-fc033a6c6b56.png?token=_EL6e3nPPtxSgvlGKURhJgrJb5NireVFT99X4BXVrYA&height=600&width=1200&expires=33267345049"> <meta name="twitter:card" content="summary_large_image"> <meta property="twitter:domain" content="accounts.imators.com"> <meta property="twitter:url" content="https://accounts.imators.com"> <meta name="twitter:title" content="Imators Auth."> <meta name="twitter:description" content="Log in to your Imators account or create one to access a multitude of features that give you control over the system at your fingertips."> <meta name="twitter:image" content="https://opengraph.b-cdn.net/production/images/fb6bc1ea-5744-46f1-bee6-fc033a6c6b56.png?token=_EL6e3nPPtxSgvlGKURhJgrJb5NireVFT99X4BXVrYA&height=600&width=1200&expires=33267345049"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Imators Auth.</title> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap" rel="stylesheet"> <script src="https://cdn.tailwindcss.com"></script> <script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script> <style> body { font-family: 'Poppins', sans-serif; } #countdown { display: none; color: red; } </style> </head> <body x-data="loginManager()" class="bg-black text-white min-h-screen flex items-center justify-center"> <div class="w-full max-w-md p-8"> <div class="text-center mb-8"> <img src="https://cdn.imators.com/logo.png" alt="Logo" class="mx-left mb-4" style="height: 60px;"> <h1 class="text-3xl text-left text-green-200">Discover the door to a multitude of functions</h1> <p class="text-sm text-left"><a class="underline" href="/register"><span class="underline text-green-300">Register</span></a> or login to your Imators account</p> </div> <div id="passkey-modal" class="fixed inset-0 bg-black bg-opacity-50 hidden z-50"> <div class="bg-black p-6 rounded-lg shadow-xl w-96 mx-auto mt-20 border border-gray-700"> <h2 class="text-xl text-white mb-4">Passkey verification</h2> <div class="flex justify-center mb-6"> <div class="animate-pulse w-16 h-16 bg-blue-500/20 rounded-full flex items-center justify-center"> <svg class="w-8 h-8 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /> </svg> </div> </div> <p class="text-gray-300 text-center mb-6">Use your Passkey to connect...</p> <button onclick="closePasskeyModal()" class="w-full border border-gray-600 text-gray-300 py-2 px-4 rounded hover:bg-gray-800 transition-colors"> Annuler </button> </div> </div> <form method="POST" x-on:submit.prevent="submitForm" class="space-y-6" > <?php if($error): ?> <div x-show="showError" class="bg-red-500 text-white p-3 rounded-lg text-center mb-4" > <?php echo htmlspecialchars($error); ?> </div> <?php endif; ?> <?php if($is_locked): ?> <div x-data="lockoutTimer(<?php echo $remaining_time; ?>)" x-init="startTimer()" class="bg-yellow-500/20 border border-yellow-500 text-yellow-300 p-4 rounded-lg text-center mb-4" > <p>Too many login attempts</p> Time remaining: <span x-text="formattedTime"></span> <a x-show="canUnlock" href="?unlock" class="mt-2 inline-block bg-green-500 text-white px-4 py-2 rounded" > Try Again </a> </div> <?php endif; ?> <div> <label class="block text-sm font-medium mb-2">Email</label> <input type="email" name="email" required <?php echo $is_locked ? 'disabled' : ''; ?> x-model="email" class="w-full px-4 py-2 rounded-lg bg-gray-900 border border-gray-800 focus:border-white focus:outline-none <?php echo $is_locked ? 'opacity-50 cursor-not-allowed' : ''; ?>" > </div> <div> <label class="block text-sm font-medium mb-2">Password</label> <div class="relative"> <input type="password" name="password" required <?php echo $is_locked ? 'disabled' : ''; ?> x-model="password" id="password-field" class="w-full px-4 py-2 rounded-lg bg-gray-900 border border-gray-800 focus:border-white focus:outline-none <?php echo $is_locked ? 'opacity-50 cursor-not-allowed' : ''; ?>" > <button type="button" class="absolute inset-y-0 right-0 pr-3 flex items-center" onclick="togglePasswordVisibility()" > <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400" id="eye-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" /> </svg> <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 hidden" id="eye-off-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l18 18" /> </svg> </button> </div> </div> <script> function togglePasswordVisibility() { const passwordField = document.getElementById('password-field'); const eyeIcon = document.getElementById('eye-icon'); const eyeOffIcon = document.getElementById('eye-off-icon'); if (passwordField.type === 'password') { passwordField.type = 'text'; eyeIcon.classList.add('hidden'); eyeOffIcon.classList.remove('hidden'); } else { passwordField.type = 'password'; eyeIcon.classList.remove('hidden'); eyeOffIcon.classList.add('hidden'); } } </script> <button type="submit" <?php echo $is_locked ? 'disabled' : ''; ?> class="w-full bg-white text-black py-2 px-4 rounded-lg font-medium hover:bg-gray-100 transition-colors <?php echo $is_locked ? 'opacity-50 cursor-not-allowed' : ''; ?>" > Login </button> </form> <p class="mt-4 text-center text-sm"> <a href="./register.php" class="text-gray-400 hover:text-white">Create an account</a> </p> </div> <script> function loginManager() { return { email: '', password: '', showError: <?php echo $error ? 'true' : 'false'; ?>, submitForm() { if (!this.email || !this.password) { this.showError = true; return; } document.querySelector('form').submit(); } }; } function lockoutTimer(initialTime) { return { remainingTime: initialTime, canUnlock: false, formattedTime: '', startTimer() { const updateTimer = () => { if (this.remainingTime > 0) { const minutes = Math.floor(this.remainingTime / 60); const seconds = this.remainingTime % 60; this.formattedTime = `${minutes} min ${seconds} sec`; this.remainingTime--; setTimeout(updateTimer, 1000); } else { this.canUnlock = true; this.formattedTime = 'Unlocked'; } }; updateTimer(); } } } </script> <script> function base64ToArrayBuffer(base64) { const binaryString = window.atob(base64); const bytes = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes.buffer; } function arrayBufferToBase64(buffer) { const bytes = new Uint8Array(buffer); let binary = ''; for (let i = 0; i < bytes.byteLength; i++) { binary += String.fromCharCode(bytes[i]); } return window.btoa(binary); } function showError(message) { const errorDiv = document.createElement('div'); errorDiv.className = 'bg-red-500 text-white p-3 rounded-lg text-center mb-4'; errorDiv.textContent = message; const existingError = document.querySelector('.bg-red-500'); if (existingError) { existingError.remove(); } document.querySelector('form').insertBefore(errorDiv, document.querySelector('form').firstChild); } function showPasskeyModal() { document.getElementById('passkey-modal').classList.remove('hidden'); } function closePasskeyModal() { document.getElementById('passkey-modal').classList.add('hidden'); } async function handlePasskeyAuth(challenge) { try { const credential = await navigator.credentials.get({ publicKey: { challenge: base64ToArrayBuffer(challenge), rpId: window.location.hostname, timeout: 60000, userVerification: "preferred" } }); const response = await fetch('../auth/verify-passkey.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: credential.id, rawId: arrayBufferToBase64(credential.rawId), response: { clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON), authenticatorData: arrayBufferToBase64(credential.response.authenticatorData), signature: arrayBufferToBase64(credential.response.signature) } }) }); const result = await response.json(); if (result.success) { window.location.href = '/dashboard'; } else { throw new Error(result.error); } } catch (error) { closePasskeyModal(); showError(error.message || 'Échec de l\'authentification Passkey'); } } document.querySelector('form').addEventListener('submit', async function(e) { e.preventDefault(); try { const formData = new FormData(this); const response = await fetch(window.location.href, { method: 'POST', body: formData }); const contentType = response.headers.get('content-type'); if (contentType && contentType.includes('application/json')) { const result = await response.json(); if (result.status === 'passkey_required') { showPasskeyModal(); await handlePasskeyAuth(result.challenge); } else { showError(result.error || 'Échec de la connexion'); } } else { window.location.href = 'https://formore.tv/account'; } } catch (error) { showError('Une erreur est survenue lors de la connexion'); } }); function loginManager() { return { email: '', password: '', showError: <?php echo $error ? 'true' : 'false'; ?>, submitForm() { if (!this.email || !this.password) { this.showError = true; return; } document.querySelector('form').submit(); } }; } function lockoutTimer(initialTime) { return { remainingTime: initialTime, canUnlock: false, formattedTime: '', startTimer() { const updateTimer = () => { if (this.remainingTime > 0) { const minutes = Math.floor(this.remainingTime / 60); const seconds = this.remainingTime % 60; this.formattedTime = `${minutes} min ${seconds} sec`; this.remainingTime--; setTimeout(updateTimer, 1000); } else { this.canUnlock = true; this.formattedTime = 'Unlocked'; } }; updateTimer(); } }; } </script> </body> </html>
| ver. 1.6 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0.01 |
proxy
|
phpinfo
|
Настройка