| Server IP : 3.111.61.48 / Your IP : 216.73.216.67 Web Server : Apache System : Linux ip-10-0-5-176 6.8.0-1057-aws #60~22.04.1-Ubuntu SMP Wed May 27 08:16:59 UTC 2026 x86_64 User : ubuntu ( 1000) PHP Version : 8.2.31 Disable Function : exec,passthru,shell_exec,system MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/vhost/book.gyaniguru.org/ |
Upload File : |
<?php
require_once 'includes/db.php';
require_once 'includes/mail.php';
session_start();
$error = '';
$message = '';
$step = 'email';
$email = '';
$user_id = null;
// Step 1: Email → generate OTP
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['send_otp'])) {
$email = trim($_POST['email'] ?? '');
if (empty($email)) {
$error = 'Please enter your email address.';
} else {
$user = get_row("SELECT id, name FROM users WHERE email = ?", [$email]);
if ($user) {
$otp = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
$expires = date('Y-m-d H:i:s', strtotime('+10 minutes'));
query("UPDATE users SET reset_token = ?, reset_expires = ? WHERE id = ?", [$otp, $expires, $user['id']]);
$sent = sendOtpEmail($email, $user['name'], $otp);
if ($sent) {
$_SESSION['reset_email'] = $email;
$_SESSION['reset_user_id'] = $user['id'];
$step = 'otp';
$message = 'An OTP has been sent to <strong>' . htmlspecialchars($email) . '</strong>. Please check your inbox.';
} else {
$error = 'Failed to send OTP email. Please check the mail configuration or try again later.';
}
} else {
$error = 'No account found with this email address.';
}
}
}
// Step 2: OTP → verify
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['verify_otp'])) {
$otp_input = trim($_POST['otp'] ?? '');
$email = $_SESSION['reset_email'] ?? '';
$user_id = $_SESSION['reset_user_id'] ?? null;
if (empty($otp_input)) {
$error = 'Please enter the OTP.';
} elseif (!$user_id) {
$error = 'Session expired. Please start again.';
} else {
$user = get_row("SELECT id FROM users WHERE id = ? AND reset_token = ? AND reset_expires > NOW()", [$user_id, $otp_input]);
if ($user) {
$step = 'reset';
} else {
$error = 'Invalid or expired OTP. Please request a new one.';
}
}
}
// Step 3: New password
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['reset_password'])) {
$password = $_POST['password'] ?? '';
$confirm = $_POST['confirm_password'] ?? '';
$user_id = $_SESSION['reset_user_id'] ?? null;
if (strlen($password) < 6) {
$error = 'Password must be at least 6 characters.';
} elseif ($password !== $confirm) {
$error = 'Passwords do not match.';
} elseif (!$user_id) {
$error = 'Session expired. Please start again.';
} else {
$hash = password_hash($password, PASSWORD_DEFAULT);
query("UPDATE users SET password = ?, reset_token = NULL, reset_expires = NULL WHERE id = ?", [$hash, $user_id]);
unset($_SESSION['reset_email'], $_SESSION['reset_user_id']);
echo '<div class="auth-wrapper" data-aos="zoom-in"><div class="auth-container"><div class="auth-form-panel" style="margin:0 auto"><div class="auth-form-inner text-center py-5">
<i class="bi bi-check-circle-fill" style="font-size:3rem;color:#059669"></i>
<h3 class="mt-3 fw-bold" style="color:var(--maroon)">Password Reset Successfully!</h3>
<p class="text-muted">Redirecting to login...</p>
<a href="login.php" class="btn btn-saffron px-4 mt-2">Login Now</a>
</div></div></div></div>';
include 'includes/footer.php';
exit();
}
}
// Resume step from session if page is refreshed
if (!isset($step) || $step === 'otp') {
if (isset($_SESSION['reset_email']) && !isset($_POST['send_otp']) && !isset($_POST['verify_otp']) && !isset($_POST['reset_password'])) {
$step = 'otp';
$message = 'Enter the OTP sent to <strong>' . htmlspecialchars($_SESSION['reset_email']) . '</strong>.';
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Forgot Password — GyaniGuru by JMC</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/auth.css">
<style>
.otp-input-wrap { display:flex; gap:8px; justify-content:center; margin:16px 0 }
.otp-input-wrap input { width:48px; height:56px; text-align:center; font-size:1.4rem; font-weight:700; border:2px solid #e0ddd8; border-radius:10px; outline:none; transition:border-color .2s }
.otp-input-wrap input:focus { border-color:var(--gold); box-shadow:0 0 0 3px rgba(212,175,55,.15) }
.otp-input-wrap input::-webkit-outer-spin-button,
.otp-input-wrap input::-webkit-inner-spin-button { -webkit-appearance:none; margin:0 }
.otp-input-wrap input[type=number] { -moz-appearance:textfield }
.step-indicator { display:flex; justify-content:center; gap:8px; margin-bottom:20px }
.step-dot { width:10px; height:10px; border-radius:50%; background:#e0ddd8; transition:all .3s }
.step-dot.active { background:var(--gold); width:28px; border-radius:5px }
</style>
</head>
<body class="auth-body">
<div class="auth-bg" id="authBg"></div>
<a href="login.php" class="auth-back-btn">
<i class="bi bi-arrow-left"></i> Back to Login
</a>
<div class="auth-wrapper" data-aos="zoom-in">
<div class="auth-container">
<div class="auth-brand-panel">
<div class="auth-brand-art">🕉️</div>
<div class="auth-brand-content text-center">
<div class="auth-om-symbol">🔱</div>
<h2 class="auth-brand-title">GyaniGuru by JMC</h2>
<div class="auth-brand-sub">AUTHENTIC VEDIC WISDOM</div>
<div class="auth-brand-divider">✦ ✦ ✦</div>
<p class="auth-brand-quote">"Do not fret, dear seeker. The path shall be restored to you."</p>
</div>
</div>
<div class="auth-form-panel">
<div class="auth-form-inner">
<div class="step-indicator">
<div class="step-dot <?php echo $step == 'email' ? 'active' : ''; ?>"></div>
<div class="step-dot <?php echo $step == 'otp' ? 'active' : ''; ?>"></div>
<div class="step-dot <?php echo $step == 'reset' ? 'active' : ''; ?>"></div>
</div>
<?php if ($error): ?>
<div class="auth-alert auth-alert-error">
<i class="bi bi-exclamation-octagon-fill"></i>
<span><?php echo $error; ?></span>
</div>
<?php endif; ?>
<?php if ($message): ?>
<div class="auth-alert" style="background:rgba(16,185,129,.1);border:1px solid rgba(16,185,129,.3);color:#065f46;border-radius:12px;padding:14px 18px;display:flex;align-items:flex-start;gap:10px;margin-bottom:16px">
<i class="bi bi-check-circle-fill" style="color:#059669;font-size:1.2rem;flex-shrink:0;margin-top:2px"></i>
<div><?php echo $message; ?></div>
</div>
<?php endif; ?>
<?php if ($step == 'email'): ?>
<div class="auth-form-header">
<h1 class="auth-form-title">Forgot Password 🙏</h1>
<p class="auth-form-subtitle">Enter your email to receive an OTP.</p>
</div>
<form action="" method="POST">
<div class="auth-field-group">
<label class="auth-label">Email Address</label>
<div class="auth-input-wrap">
<i class="bi bi-envelope auth-input-icon"></i>
<input type="email" name="email" class="auth-input" required placeholder="Enter your registered email">
</div>
</div>
<button type="submit" name="send_otp" class="auth-submit-btn">
<span>Send OTP</span> <i class="bi bi-send"></i>
</button>
</form>
<?php elseif ($step == 'otp'): ?>
<div class="auth-form-header">
<h1 class="auth-form-title">Verify OTP 🔢</h1>
<p class="auth-form-subtitle">Enter the 6-digit code sent to your email.</p>
</div>
<form action="" method="POST" id="otpForm">
<div class="otp-input-wrap" id="otpInputs">
<input type="number" name="otp1" class="otp-box" maxlength="1" autofocus>
<input type="number" name="otp2" class="otp-box" maxlength="1">
<input type="number" name="otp3" class="otp-box" maxlength="1">
<input type="number" name="otp4" class="otp-box" maxlength="1">
<input type="number" name="otp5" class="otp-box" maxlength="1">
<input type="number" name="otp6" class="otp-box" maxlength="1">
</div>
<input type="hidden" name="otp" id="otpHidden">
<button type="submit" name="verify_otp" class="auth-submit-btn">
<span>Verify OTP</span> <i class="bi bi-check-circle"></i>
</button>
</form>
<div class="text-center mt-3">
<a href="forgot-password.php" class="text-muted" style="font-size:.85rem">Request new OTP</a>
</div>
<?php elseif ($step == 'reset'): ?>
<div class="auth-form-header">
<h1 class="auth-form-title">Reset Password 🔐</h1>
<p class="auth-form-subtitle">Choose a new password for your account.</p>
</div>
<form action="" method="POST">
<div class="auth-field-group">
<label class="auth-label">New Password</label>
<div class="auth-input-wrap">
<i class="bi bi-key auth-input-icon"></i>
<input type="password" name="password" id="passwordInput" class="auth-input" required minlength="6" placeholder="Min 6 characters">
<button type="button" class="auth-eye-btn" onclick="togglePassword()">
<i class="bi bi-eye" id="eyeIcon"></i>
</button>
</div>
</div>
<div class="auth-field-group">
<label class="auth-label">Confirm Password</label>
<div class="auth-input-wrap">
<i class="bi bi-shield-check auth-input-icon"></i>
<input type="password" name="confirm_password" class="auth-input" required minlength="6" placeholder="Re-enter new password">
</div>
</div>
<button type="submit" name="reset_password" class="auth-submit-btn">
<span>Reset Password</span> <i class="bi bi-check-circle"></i>
</button>
</form>
<?php endif; ?>
<p class="auth-switch-text mt-3">
Remember your password? <a href="login.php" class="auth-switch-link">Login</a>
</p>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.js"></script>
<script>
AOS.init();
const bg = document.getElementById('authBg');
for(let i=0; i<20; i++){
const p = document.createElement('div');
p.className = 'auth-particle';
p.style.cssText = `left:${Math.random()*100}%;width:${Math.random()*4+2}px;height:${Math.random()*4+2}px;animation-duration:${Math.random()*15+10}s;animation-delay:${Math.random()*10}s`;
bg.appendChild(p);
}
// OTP auto-focus
const boxes = document.querySelectorAll('.otp-box');
if (boxes.length) {
boxes.forEach(function(input, idx) {
input.addEventListener('input', function() {
if (this.value.length >= 1 && idx < boxes.length - 1) {
boxes[idx + 1].focus();
}
updateOtp();
});
input.addEventListener('keydown', function(e) {
if (e.key === 'Backspace' && this.value.length === 0 && idx > 0) {
boxes[idx - 1].focus();
}
updateOtp();
});
input.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
document.getElementById('otpForm').submit();
}
});
});
}
function updateOtp() {
var val = '';
boxes.forEach(function(b) { val += b.value; });
document.getElementById('otpHidden').value = val;
}
function togglePassword() {
const input = document.getElementById('passwordInput');
const icon = document.getElementById('eyeIcon');
if(input.type === 'password'){
input.type = 'text';
icon.className = 'bi bi-eye-slash';
} else {
input.type = 'password';
icon.className = 'bi bi-eye';
}
}
</script>
</body>
</html>