Files
domnitor/app/Views/auth/reset-password.php
Hosteroid a29becc944 Add CSRF, CAPTCHA, and input validation improvements
Introduces CSRF protection to all sensitive controller actions, integrates configurable CAPTCHA (reCAPTCHA v2/v3, Turnstile) for authentication and registration flows, and centralizes input validation via a new InputValidator helper. Adds new helpers and services for CSRF and CAPTCHA, updates settings and migration for CAPTCHA configuration, and enhances logging and error handling in TLD registry import processes. Also improves validation for user, domain, group, and profile inputs throughout the application.
2025-10-10 00:04:12 +03:00

152 lines
5.7 KiB
PHP

<?php
$title = 'Reset Password';
ob_start();
?>
<!-- Logo and Title -->
<div class="text-center mb-8">
<div class="inline-flex items-center justify-center w-14 h-14 bg-primary rounded-lg mb-4">
<i class="fas fa-lock-open text-white text-2xl"></i>
</div>
<h1 class="text-2xl font-semibold text-gray-900 mb-1">Reset Password</h1>
<p class="text-sm text-gray-500">Enter your new password below</p>
</div>
<!-- Error/Success Alert -->
<?php if (isset($_SESSION['error'])): ?>
<div class="mb-6 bg-red-50 border border-red-200 p-3 rounded-lg">
<div class="flex items-center">
<i class="fas fa-exclamation-circle text-red-500 mr-2"></i>
<span class="text-sm text-red-700"><?= htmlspecialchars($_SESSION['error']) ?></span>
</div>
</div>
<?php unset($_SESSION['error']); ?>
<?php endif; ?>
<!-- Reset Password Form -->
<form method="POST" action="/reset-password" class="space-y-4">
<?= csrf_field() ?>
<!-- Hidden token field -->
<input type="hidden" name="token" value="<?= htmlspecialchars($token ?? '') ?>">
<!-- Password Field -->
<div>
<label for="password" class="block text-sm font-medium text-gray-700 mb-1.5">
New Password
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-lock text-gray-400 text-sm"></i>
</div>
<input
type="password"
id="password"
name="password"
required
minlength="8"
autofocus
class="w-full pl-10 pr-10 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
placeholder="Enter new password">
<button
type="button"
onclick="togglePassword('password')"
class="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600 focus:outline-none">
<i class="fas fa-eye text-sm" id="toggleIcon-password"></i>
</button>
</div>
<p class="text-xs text-gray-500 mt-1">Minimum 8 characters</p>
</div>
<!-- Confirm Password Field -->
<div>
<label for="password_confirm" class="block text-sm font-medium text-gray-700 mb-1.5">
Confirm New Password
</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-lock text-gray-400 text-sm"></i>
</div>
<input
type="password"
id="password_confirm"
name="password_confirm"
required
minlength="8"
class="w-full pl-10 pr-10 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-colors text-sm"
placeholder="Re-enter new password">
<button
type="button"
onclick="togglePassword('password_confirm')"
class="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600 focus:outline-none">
<i class="fas fa-eye text-sm" id="toggleIcon-password_confirm"></i>
</button>
</div>
</div>
<!-- Password Strength Indicator -->
<div class="bg-blue-50 border border-blue-200 rounded-lg p-3">
<p class="text-xs text-blue-800 mb-2">
<i class="fas fa-shield-alt mr-1"></i>
<strong>Password Requirements:</strong>
</p>
<ul class="text-xs text-blue-700 space-y-1 ml-5 list-disc">
<li>At least 8 characters long</li>
<li>Mix of uppercase and lowercase letters recommended</li>
<li>Include numbers and special characters for extra security</li>
</ul>
</div>
<!-- CAPTCHA Widget -->
<?php include __DIR__ . '/captcha-widget.php'; ?>
<!-- Submit Button -->
<button
type="submit"
class="w-full bg-primary hover:bg-primary-dark text-white py-2.5 rounded-lg font-medium transition-colors duration-200 flex items-center justify-center text-sm mt-6">
<i class="fas fa-check mr-2"></i>
Reset Password
</button>
</form>
<!-- Back to Login Link -->
<div class="text-center mt-6 pt-6 border-t border-gray-200">
<a href="/login" class="inline-flex items-center text-sm text-gray-600 hover:text-gray-800">
<i class="fas fa-arrow-left mr-2"></i>
Back to Login
</a>
</div>
<?php
$content = ob_get_clean();
$scripts = <<<'SCRIPT'
<script>
function togglePassword(fieldId) {
const passwordInput = document.getElementById(fieldId);
const toggleIcon = document.getElementById('toggleIcon-' + fieldId);
if (passwordInput.type === 'password') {
passwordInput.type = 'text';
toggleIcon.classList.remove('fa-eye');
toggleIcon.classList.add('fa-eye-slash');
} else {
passwordInput.type = 'password';
toggleIcon.classList.remove('fa-eye-slash');
toggleIcon.classList.add('fa-eye');
}
}
// Client-side password match validation
document.querySelector('form').addEventListener('submit', function(e) {
const password = document.getElementById('password').value;
const passwordConfirm = document.getElementById('password_confirm').value;
if (password !== passwordConfirm) {
e.preventDefault();
alert('Passwords do not match!');
}
});
</script>
SCRIPT;
require __DIR__ . '/base-auth.php';
?>