Phase 2: Add comprehensive audit logging
- Created AuditLogger service class (360+ lines) * 16 action type constants (LOGIN_SUCCESS, PAYMENT_FAILURE, etc.) * log() - main logging method with flexible parameters * logLogin() - specialized login audit logging * logLogout() - session termination tracking * logPasswordChange() - credential change tracking * logBookingCreate() - booking audit trail * logPayment() - payment attempt/result tracking * logMembership() - membership action tracking * logAccessDenied() - authorization failure logging * getRecentLogs() - retrieve audit history * getLogsByAction() - filter logs by action type - Integrated audit logging into validate_login.php: * Logs all login attempts (success and failures) * Captures failure reasons (invalid password, not verified, etc.) * Logs Google OAuth registrations and logins * Logs email/password login attempts * Captures IP address for each log entry * Includes timestamp (via database NOW()) - Audit Log Fields: * user_id - identifier of user performing action * action - action type (e.g., login_success) * status - success/failure/pending * ip_address - client IP (handles proxy/load balancer) * details - JSON-encoded metadata * created_at - timestamp - Design Features: * Uses DatabaseService singleton for connections * Graceful error handling (doesn't break application) * JSON serialization of complex data for analysis * IP detection handles proxies and load balancers * Constants for action types enable IDE autocomplete * Extensible for additional event types - Security Benefits: * Complete login audit trail for fraud detection * Failed login attempts tracked (detects brute force) * IP address recorded for geo-blocking/analysis * Timestamps enable timeline correlation * Action types enable targeted monitoring
This commit is contained in:
@@ -8,6 +8,7 @@ require_once 'google-client/vendor/autoload.php'; // Add this line for Google Cl
|
||||
use Middleware\CsrfMiddleware;
|
||||
use Middleware\RateLimitMiddleware;
|
||||
use Services\AuthenticationService;
|
||||
use Services\AuditLogger;
|
||||
|
||||
// Check if connection is established
|
||||
if (!$conn) {
|
||||
@@ -70,6 +71,8 @@ if (isset($_GET['code'])) {
|
||||
AuthenticationService::regenerateSession();
|
||||
// Reset rate limit on successful login
|
||||
RateLimitMiddleware::reset('login');
|
||||
// Log successful registration via Google
|
||||
AuditLogger::logLogin($email, true);
|
||||
// echo json_encode(['status' => 'success', 'message' => 'Google login successful']);
|
||||
header("Location: index.php");
|
||||
exit();
|
||||
@@ -89,6 +92,8 @@ if (isset($_GET['code'])) {
|
||||
AuthenticationService::regenerateSession();
|
||||
// Reset rate limit on successful login
|
||||
RateLimitMiddleware::reset('login');
|
||||
// Log successful Google login
|
||||
AuditLogger::logLogin($email, true);
|
||||
// echo json_encode(['status' => 'success', 'message' => 'Google login successful']);
|
||||
header("Location: index.php");
|
||||
exit();
|
||||
@@ -122,12 +127,14 @@ if (isset($_POST['email']) && isset($_POST['password'])) {
|
||||
if (empty($email) || empty($password)) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Please enter both email and password.']);
|
||||
RateLimitMiddleware::incrementAttempt('login', 900);
|
||||
AuditLogger::logLogin($email ?? 'unknown', false, 'Empty email or password');
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid email format.']);
|
||||
RateLimitMiddleware::incrementAttempt('login', 900);
|
||||
AuditLogger::logLogin($email ?? 'unknown', false, 'Invalid email format');
|
||||
exit();
|
||||
}
|
||||
|
||||
@@ -152,6 +159,7 @@ if (isset($_POST['email']) && isset($_POST['password'])) {
|
||||
if ($row['is_verified'] == 0) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Your account is not verified. Please check your email for the verification link.']);
|
||||
RateLimitMiddleware::incrementAttempt('login', 900);
|
||||
AuditLogger::logLogin($email, false, 'Account not verified');
|
||||
exit();
|
||||
}
|
||||
|
||||
@@ -164,15 +172,19 @@ if (isset($_POST['email']) && isset($_POST['password'])) {
|
||||
AuthenticationService::regenerateSession();
|
||||
// Reset rate limit on successful login
|
||||
RateLimitMiddleware::reset('login');
|
||||
// Log successful email/password login
|
||||
AuditLogger::logLogin($email, true);
|
||||
echo json_encode(['status' => 'success', 'message' => 'Successful Login']);
|
||||
} else {
|
||||
// Password is incorrect - increment rate limit
|
||||
RateLimitMiddleware::incrementAttempt('login', 900);
|
||||
AuditLogger::logLogin($email, false, 'Invalid password');
|
||||
echo json_encode(['status' => 'error', 'message' => 'Invalid password.']);
|
||||
}
|
||||
} else {
|
||||
// User does not exist - still increment rate limit to prevent email enumeration
|
||||
RateLimitMiddleware::incrementAttempt('login', 900);
|
||||
AuditLogger::logLogin($email, false, 'User not found');
|
||||
echo json_encode(['status' => 'error', 'message' => 'User with that email does not exist.']);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user