Deploy: 2026-05-21 01:26:06

This commit is contained in:
Hamza-Ayed
2026-05-21 01:26:06 +03:00
parent 146ebd7200
commit 16d494b4e1
13 changed files with 816 additions and 32 deletions

View File

@@ -0,0 +1,147 @@
<?php
namespace App\Controllers;
use App\Core\Request;
use App\Core\Response;
use App\Core\Security;
use App\Models\User;
use App\Models\Company;
class AuthController extends BaseController
{
/**
* Register a new company and admin user
*/
public function register(Request $request, Response $response): void
{
$errors = $this->validate($request, [
'company_name' => 'required|min:3',
'user_name' => 'required|min:3',
'email' => 'required|email',
'password' => 'required|strong_password'
]);
if (!empty($errors)) {
$response->json(['errors' => $errors], 400);
return;
}
$data = $request->getBody();
// Check if user already exists securely via Blind Index
$existingUser = User::findByEmail($data['email']);
if ($existingUser) {
$response->json(['errors' => ['email' => ['This email is already registered.']]], 409);
return;
}
try {
// Create Company
$companyId = Company::create([
'name' => htmlspecialchars(strip_tags($data['company_name']))
]);
// Create Admin User for this Company
$userId = User::createSecure([
'company_id' => $companyId,
'name' => htmlspecialchars(strip_tags($data['user_name'])),
'email' => strtolower(trim($data['email'])),
'password' => $data['password'],
'role' => 'admin'
]);
$response->json([
'message' => 'Company and Admin user registered successfully.',
'company_id' => $companyId,
'user_id' => $userId
], 201);
} catch (\Exception $e) {
error_log("Registration Error: " . $e->getMessage());
$response->json(['error' => 'An error occurred during registration.'], 500);
}
}
/**
* Login existing user and return JWT
*/
public function login(Request $request, Response $response): void
{
$errors = $this->validate($request, [
'email' => 'required|email',
'password' => 'required'
]);
if (!empty($errors)) {
$response->json(['errors' => $errors], 400);
return;
}
$data = $request->getBody();
// Find user by email blind index
$user = User::findByEmail($data['email']);
if (!$user) {
$response->json(['error' => 'Invalid email or password'], 401);
return;
}
// Verify password hash
if (!Security::verifyPassword($data['password'], $user['password'])) {
$response->json(['error' => 'Invalid email or password'], 401);
return;
}
if ($user['status'] !== 'active') {
$response->json(['error' => 'Your account is inactive or suspended.'], 403);
return;
}
// Generate standard JWT token with full required payload
$payload = [
'user_id' => $user['id'],
'company_id' => $user['company_id'],
'role' => $user['role']
];
$token = Security::generateJWT($payload);
$response->json([
'message' => 'Login successful',
'token' => $token,
'user' => [
'id' => $user['id'],
'company_id' => $user['company_id'],
'name' => $user['name'],
'role' => $user['role']
]
], 200);
}
/**
* Get current logged in user details
* (Protected by AuthMiddleware)
*/
public function me(Request $request, Response $response): void
{
$user = User::find($request->user_id);
if (!$user) {
$response->json(['error' => 'User not found'], 404);
return;
}
$response->json([
'user' => [
'id' => $user['id'],
'company_id' => $user['company_id'],
'name' => $user['name'],
'email' => Security::decrypt($user['email']), // Decrypt email before sending back
'role' => $user['role'],
'status' => $user['status'],
'created_at' => $user['created_at']
]
]);
}
}

View File

@@ -19,31 +19,8 @@ class BaseController
*/
protected function validate(Request $request, array $rules): array
{
$errors = [];
$data = $request->getBody();
foreach ($rules as $field => $constraints) {
$value = $data[$field] ?? null;
$constraintsArray = explode('|', $constraints);
foreach ($constraintsArray as $constraint) {
if ($constraint === 'required') {
if ($value === null || $value === '') {
$errors[$field][] = "The {$field} field is required.";
}
} elseif ($constraint === 'email') {
if ($value !== null && $value !== '' && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
$errors[$field][] = "The {$field} must be a valid email address.";
}
} elseif (strpos($constraint, 'min:') === 0) {
$min = (int) substr($constraint, 4);
if ($value !== null && strlen((string)$value) < $min) {
$errors[$field][] = "The {$field} must be at least {$min} characters.";
}
}
}
}
return $errors;
$validator = new \App\Core\Validator();
$validator->validate($request->getBody(), $rules);
return $validator->getErrors();
}
}