71 lines
1.9 KiB
PHP
71 lines
1.9 KiB
PHP
<?php
|
|
/**
|
|
* Auth Login Endpoint
|
|
*/
|
|
|
|
use App\Core\Database;
|
|
use App\Core\JWT;
|
|
use App\Core\Validator;
|
|
|
|
use App\Middleware\RateLimitMiddleware;
|
|
use App\Core\Security;
|
|
|
|
// 0. Rate Limiting (5 attempts per minute per IP)
|
|
RateLimitMiddleware::check(5, 60);
|
|
|
|
$data = Security::sanitize(input());
|
|
|
|
// 1. Validation
|
|
$errors = Validator::validate($data, [
|
|
'email' => 'required|email',
|
|
'password' => 'required'
|
|
]);
|
|
|
|
if ($errors) {
|
|
json_error('Validation Failed', 422, $errors);
|
|
}
|
|
|
|
$email = $data['email'];
|
|
$password = $data['password'];
|
|
|
|
// 2. DB Check (Using hash for lookup since email is encrypted)
|
|
$db = Database::getInstance();
|
|
$emailHash = hash('sha256', strtolower($email));
|
|
$stmt = $db->prepare("SELECT * FROM users WHERE email_hash = ? LIMIT 1");
|
|
$stmt->execute([$emailHash]);
|
|
$user = $stmt->fetch();
|
|
|
|
if (!$user || !password_verify($password, $user['password_hash'])) {
|
|
json_error('بيانات الدخول غير صحيحة', 401);
|
|
}
|
|
|
|
// 3. Issue Token
|
|
$secret = env('JWT_SECRET');
|
|
if (!$secret || strlen($secret) < 32) {
|
|
error_log('FATAL: JWT_SECRET is missing or too short in .env');
|
|
json_error('Server configuration error', 500);
|
|
}
|
|
$payload = [
|
|
'user_id' => $user['id'],
|
|
'role' => $user['role'],
|
|
'exp' => time() + (15 * 60) // 15 minutes
|
|
];
|
|
|
|
$token = JWT::encode($payload, $secret);
|
|
|
|
// 4. Update Refresh Token (Hashed before storage for security)
|
|
$refreshToken = bin2hex(random_bytes(32));
|
|
$refreshTokenHash = hash('sha256', $refreshToken);
|
|
$stmt = $db->prepare("UPDATE users SET refresh_token_hash = ? WHERE id = ?");
|
|
$stmt->execute([$refreshTokenHash, $user['id']]);
|
|
|
|
json_success([
|
|
'access_token' => $token,
|
|
'refresh_token' => $refreshToken,
|
|
'user' => [
|
|
'id' => $user['id'],
|
|
'name' => (App\Core\Encryption::decrypt($user['name']) ?: $user['name']),
|
|
'email' => (App\Core\Encryption::decrypt($user['email']) ?: $user['email'])
|
|
]
|
|
], 'تم تسجيل الدخول بنجاح');
|