Mini Shell
<?php
session_start();
session_destroy();
if(isset($_COOKIE['username']) && isset($_COOKIE['password'])){
unset($_COOKIE['username']);
unset($_COOKIE['password']);
setcookie('username', null, -1, '/');
setcookie('password', null, -1, '/');}
// Check if form was submitted
$success = isset($_GET['success']) && $_GET['success'] == 'true';
$error = isset($_GET['error']) && $_GET['error'] == 'true';
$error_message = isset($_GET['message']) ? $_GET['message'] : '';
$rootPath = realpath(dirname(__FILE__) . '/..');
require_once $rootPath . '/Portal/config/config.php'; // Use clean config file
// Start session BEFORE any output
session_start();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<link href="img/loogo.png" rel="icon">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MHC - IMS</title>
<!-- Add CSRF Token Meta Tag -->
<meta name="csrf-token" content="<?php echo bin2hex(random_bytes(32)); ?>">
<style>
:root {
--primary-color: #2e7d32; /* Changed from blue to green */
--secondary-color: #1b5e20; /* Changed from blue to dark green */
--success-color: #27ae60;
--warning-color: #f39c12;
--danger-color: #e74c3c;
--light-color: #ecf0f1;
--dark-color: #1b5e20; /* Changed from blue to dark green */
--sidebar-width: 250px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: #ffffff; /* Changed from #f5f7fa to pure white */
color: #333;
min-height: 100vh;
background-image: url('Portal/img/Background.jpeg');
background-size: cover;
background-position: center;
background-attachment: fixed;
background-repeat: no-repeat;
}
/* Login Container */
.login-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: rgba(255, 255, 255, 0.9); /* Changed from gradient to white with transparency */
padding: 20px;
}
.login-box {
background: white;
border-radius: 15px;
padding: 40px;
width: 100%;
max-width: 500px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.login-header {
text-align: center;
margin-bottom: 30px;
}
.login-logo {
font-size: 32px;
color: var(--primary-color);
margin-bottom: 10px;
}
.login-title {
font-size: 24px;
color: var(--secondary-color);
margin-bottom: 5px;
}
.login-subtitle {
color: #7f8c8d;
font-size: 14px;
}
.user-type-selector {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
margin-bottom: 20px;
}
.user-type-btn {
padding: 10px;
border: 2px solid #ddd;
background: white;
border-radius: 5px;
cursor: pointer;
text-align: center;
transition: all 0.3s;
}
.user-type-btn.active {
border-color: var(--primary-color);
background: var(--primary-color);
color: white;
}
.user-type-btn i {
font-size: 24px;
margin-bottom: 5px;
display: block;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: var(--secondary-color);
}
input, select {
width: 100%;
padding: 12px 15px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 16px;
transition: all 0.3s;
}
input:focus, select:focus {
border-color: var(--primary-color);
outline: none;
box-shadow: 0 0 0 3px rgba(46, 125, 50, 0.2); /* Changed from blue to green */
}
.btn {
padding: 14px 20px;
border: none;
border-radius: 5px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.btn-primary {
background: var(--primary-color);
color: white;
width: 100%;
}
.btn-primary:hover {
background: #1b5e20; /* Changed from blue to dark green */
}
.btn-success {
background: var(--success-color);
color: white;
}
.btn-danger {
background: var(--danger-color);
color: white;
}
.alert {
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
font-size: 14px;
}
.alert-success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.alert-error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.alert-info {
background: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
.debug-info {
background: #f8f9fa;
border: 1px solid #ddd;
border-radius: 5px;
padding: 15px;
margin-top: 20px;
font-family: 'Courier New', monospace;
font-size: 12px;
max-height: 300px;
overflow-y: auto;
}
.debug-info h4 {
margin-bottom: 10px;
color: #6c757d;
}
.debug-info pre {
white-space: pre-wrap;
word-wrap: break-word;
}
.system-actions {
display: flex;
gap: 10px;
margin-top: 20px;
flex-wrap: wrap;
}
.system-actions .btn {
flex: 1;
min-width: 150px;
padding: 10px;
font-size: 14px;
}
.demo-credentials {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 5px;
padding: 15px;
margin-top: 20px;
font-size: 13px;
}
.demo-credentials h4 {
color: var(--secondary-color);
margin-bottom: 10px;
font-size: 14px;
}
.demo-credentials table {
width: 100%;
border-collapse: collapse;
}
.demo-credentials td {
padding: 5px;
border-bottom: 1px solid #eee;
}
.demo-credentials td:first-child {
font-weight: 600;
color: var(--primary-color);
}
.troubleshooting {
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 5px;
padding: 15px;
margin-top: 20px;
font-size: 13px;
}
.troubleshooting h4 {
color: #856404;
margin-bottom: 10px;
font-size: 14px;
}
.troubleshooting ul {
padding-left: 20px;
}
.troubleshooting li {
margin-bottom: 5px;
}
@media (max-width: 768px) {
.login-box {
padding: 20px;
}
.user-type-selector {
grid-template-columns: repeat(2, 1fr);
}
.system-actions .btn {
min-width: 100%;
}
}
/* ... (existing styles remain) ... */
/* Security Indicators */
.password-strength {
margin-top: 5px;
height: 5px;
border-radius: 3px;
background: #eee;
overflow: hidden;
}
.strength-bar {
height: 100%;
width: 0;
transition: width 0.3s;
}
.weak { background: #e74c3c; }
.medium { background: #f39c12; }
.strong { background: #27ae60; }
/* Security badge */
.security-badge {
position: fixed;
bottom: 20px;
right: 20px;
background: #2e7d32; /* Changed from blue to green */
color: white;
padding: 8px 15px;
border-radius: 20px;
font-size: 12px;
opacity: 0.8;
z-index: 1000;
}
/* Error message styling */
.error-message {
color: #e74c3c;
font-size: 14px;
margin-top: 5px;
display: none;
}
/* CAPTCHA styling */
.captcha-container {
background: #f8f9fa;
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
text-align: center;
}
.captcha-code {
font-family: 'Courier New', monospace;
font-size: 24px;
font-weight: bold;
letter-spacing: 5px;
background: white;
padding: 10px;
border-radius: 3px;
margin: 10px 0;
user-select: none;
}
/* Login attempts warning */
.attempts-warning {
background: #fff3cd;
border: 1px solid #ffeaa7;
padding: 10px;
border-radius: 5px;
font-size: 13px;
margin-bottom: 15px;
}
/* Rate limiting indicator */
.rate-limit {
display: none;
background: #f8d7da;
border: 1px solid #f5c6cb;
padding: 10px;
border-radius: 5px;
margin-bottom: 15px;
font-size: 14px;
}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
<?php
?>
<!-- Login Page -->
<div class="login-container">
<div class="login-box">
<div class="login-header">
<div class="school-logo">
<img class="img-fluid" src="img/loogo.png" width="50" height="60" alt="">
</div>
<h2 class="login-title">MHC IMS</h2>
<p class="login-subtitle">Please login to continue</p>
<?php include('./include/flash_messages.php') ?>
<!-- Rate limiting warning -->
<?php
$failed_attempts = $_SESSION['failed_login_attempts'] ?? 0;
if ($failed_attempts >= 3): ?>
<div class="attempts-warning">
<i class="fas fa-exclamation-triangle"></i>
Multiple failed login attempts detected. Please wait before trying again.
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="alert alert-success">
<i class="fas fa-check-circle"></i> Password reset email sent, Please check your email
</div>
<?php endif; ?>
<?php if ($error): ?>
<div class="alert alert-error">
<i class="fas fa-exclamation-circle"></i>
<?php echo htmlspecialchars($error_message ?: 'There was an error sending your message. Please try again.'); ?>
</div>
<?php endif; ?>
<!-- Session timeout warning -->
<?php if (isset($_SESSION['session_timeout'])): ?>
<div class="alert alert-info">
<i class="fas fa-clock"></i> Your session has expired. Please login again.
</div>
<?php unset($_SESSION['session_timeout']); endif; ?>
</div>
<!-- Hidden CSRF Token -->
<?php
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>
<input type="hidden" name="csrf_token" id="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<!-- Rate limit counter -->
<input type="hidden" name="last_attempt_time" id="last_attempt_time"
value="<?php echo $_SESSION['last_login_attempt'] ?? 0; ?>">
<form class="form loginform" method="POST" action="authenticate.php" id="loginForm">
<div class="form-group">
<label for="username">
<i class="fas fa-user"></i> Username
</label>
<input type="text" id="username" name="username" required
placeholder="Enter your username"
value="<?php echo htmlspecialchars($_COOKIE['username'] ?? ''); ?>"
maxlength="50"
autocomplete="username"
oninput="validateUsername(this)">
<div class="error-message" id="username-error"></div>
</div>
<div class="form-group">
<label for="password">
<i class="fas fa-lock"></i> Password
</label>
<input type="password" id="password" name="passwd" required
placeholder="Enter your password"
maxlength="100"
autocomplete="current-password"
oninput="checkPasswordStrength(this.value)">
<div class="password-strength">
<div class="strength-bar" id="password-strength-bar"></div>
</div>
<div class="error-message" id="password-error"></div>
</div>
<!-- CAPTCHA Section -->
<?php if ($failed_attempts >= 2): ?>
<div class="form-group">
<label>Security Verification</label>
<div class="captcha-container">
<?php
$captcha_num1 = rand(1, 10);
$captcha_num2 = rand(1, 10);
$_SESSION['captcha_answer'] = $captcha_num1 + $captcha_num2;
?>
<p>What is <?php echo $captcha_num1; ?> + <?php echo $captcha_num2; ?> ?</p>
<input type="text" name="captcha" required
placeholder="Enter the answer"
maxlength="3"
pattern="\d+"
class="form-control">
</div>
</div>
<?php endif; ?>
<!-- Remember me option -->
<div class="form-group">
<label style="display: inline-flex; align-items: center; cursor: pointer;">
<input type="checkbox" name="remember" value="1"
style="width: auto; margin-right: 8px;"
<?php echo isset($_COOKIE['username']) ? 'checked' : ''; ?>>
<span>Remember me on this device</span>
</label>
<small style="color: #666; display: block; margin-top: 5px;">
<i class="fas fa-info-circle"></i> Only use on trusted devices
</small>
</div>
<!-- Rate limiting message -->
<div class="rate-limit" id="rateLimitMessage">
<i class="fas fa-hourglass-half"></i> Please wait before trying again.
</div>
<?php if(isset($_SESSION['login_failure'])): ?>
<div class="alert alert-danger alert-dismissable fade in">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
<?php echo $_SESSION['login_failure']; unset($_SESSION['login_failure']);?>
</div>
<?php endif; ?>
<!-- CSRF Token -->
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<!-- Timestamp for replay attack prevention -->
<input type="hidden" name="timestamp" value="<?php echo time(); ?>">
<!-- CAPTCHA (conditionally displayed) -->
<?php if (isset($_SESSION['failed_login_attempts']) && $_SESSION['failed_login_attempts'] >= 2): ?>
<div class="form-group">
<label>Security Verification *</label>
<div class="captcha-container">
<?php
// Generate CAPTCHA if not exists
if (!isset($_SESSION['captcha_answer'])) {
$num1 = rand(1, 10);
$num2 = rand(1, 10);
$_SESSION['captcha_answer'] = $num1 + $num2;
$captcha_question = "$num1 + $num2 = ?";
} else {
// Regenerate CAPTCHA occasionally
$num1 = rand(1, 10);
$num2 = rand(1, 10);
$_SESSION['captcha_answer'] = $num1 + $num2;
$captcha_question = "$num1 + $num2 = ?";
}
?>
<p><?php echo $captcha_question; ?></p>
<input type="number" name="captcha" required
placeholder="Enter the answer"
class="form-control"
min="2"
max="20">
</div>
</div>
<?php endif; ?>
<button type="submit" name="login" class="btn btn-primary col-lg-4" id="loginButton">
<i class="fas fa-sign-in-alt"></i> Login
</button>
<div style="margin-top: 20px; text-align: center;">
<a href="../"><i class="fas fa-home"></i> Home</a>
<a href="Forgot_Password"><i class="fas fa-lock"></i> Forgot password</a>
</div>
</form>
<!-- Security information modal (hidden by default) -->
<div id="securityInfo" style="display: none; margin-top: 20px; padding: 15px; background: #f8f9fa; border-radius: 5px;">
<h4><i class="fas fa-shield-alt"></i> Security Features</h4>
<ul>
<li><strong>CSRF Protection:</strong> Prevents cross-site request forgery attacks</li>
<li><strong>Rate Limiting:</strong> Blocks excessive login attempts</li>
<li><strong>Input Validation:</strong> All inputs are sanitized</li>
<li><strong>Session Security:</strong> Secure session management</li>
<li><strong>CAPTCHA:</strong> Required after failed attempts</li>
</ul>
</div>
</div>
</div>
<!-- Security badge -->
<div class="security-badge">
<i class="fas fa-lock"></i> Secure Login
</div>
<!-- JavaScript Security Enhancements -->
<script>
// Track login attempts
let loginAttempts = <?php echo $failed_attempts; ?>;
let lastAttemptTime = <?php echo $_SESSION['last_login_attempt'] ?? 0; ?>;
let currentTime = Math.floor(Date.now() / 1000);
// Check rate limiting
if (loginAttempts >= 3 && (currentTime - lastAttemptTime) < 300) {
document.getElementById('rateLimitMessage').style.display = 'block';
document.getElementById('loginButton').disabled = true;
setTimeout(() => {
document.getElementById('loginButton').disabled = false;
document.getElementById('rateLimitMessage').style.display = 'none';
}, 300000); // 5 minutes
}
// Password strength indicator
function checkPasswordStrength(password) {
let strengthBar = document.getElementById('password-strength-bar');
let strength = 0;
if (password.length >= 8) strength++;
if (/[A-Z]/.test(password)) strength++;
if (/[0-9]/.test(password)) strength++;
if (/[^A-Za-z0-9]/.test(password)) strength++;
let width = strength * 25;
strengthBar.style.width = width + '%';
if (strength < 2) {
strengthBar.className = 'strength-bar weak';
} else if (strength < 4) {
strengthBar.className = 'strength-bar medium';
} else {
strengthBar.className = 'strength-bar strong';
}
}
// Username validation
function validateUsername(input) {
let errorDiv = document.getElementById('username-error');
let username = input.value.trim();
if (username.length < 3) {
errorDiv.textContent = 'Username must be at least 3 characters';
errorDiv.style.display = 'block';
return false;
}
if (!/^[a-zA-Z0-9_\-@.]+$/.test(username)) {
errorDiv.textContent = 'Username contains invalid characters';
errorDiv.style.display = 'block';
return false;
}
errorDiv.style.display = 'none';
return true;
}
// Form validation before submission
document.getElementById('loginForm').addEventListener('submit', function(e) {
// Check rate limiting
if (loginAttempts >= 3 && (currentTime - lastAttemptTime) < 300) {
e.preventDefault();
alert('Too many login attempts. Please wait 5 minutes.');
return false;
}
// Validate username
if (!validateUsername(document.getElementById('username'))) {
e.preventDefault();
return false;
}
// Check password length
let password = document.getElementById('password').value;
if (password.length < 6) {
e.preventDefault();
document.getElementById('password-error').textContent = 'Password must be at least 6 characters';
document.getElementById('password-error').style.display = 'block';
return false;
}
// Add timestamp to prevent replay attacks
let timestampInput = document.createElement('input');
timestampInput.type = 'hidden';
timestampInput.name = 'timestamp';
timestampInput.value = Math.floor(Date.now() / 1000);
this.appendChild(timestampInput);
// Disable button to prevent double submission
document.getElementById('loginButton').disabled = true;
document.getElementById('loginButton').innerHTML = '<i class="fas fa-spinner fa-spin"></i> Logging in...';
return true;
});
// Show security info
function showSecurityInfo() {
let infoDiv = document.getElementById('securityInfo');
infoDiv.style.display = infoDiv.style.display === 'none' ? 'block' : 'none';
}
// Auto-focus on username field
window.onload = function() {
document.getElementById('username').focus();
}
</script>
</body>
</html>