feat: Authentication
- Update User model - Create authentication controller - Update api router
هذا الالتزام موجود في:
128
app/Http/Controllers/AuthController.php
Normal file
128
app/Http/Controllers/AuthController.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Http\Requests\RegisterUserRequest;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
public function register(Request $request)
|
||||
{
|
||||
// If we reach here, validation has already passed!
|
||||
// Laravel automatically validates using our RegisterUserRequest
|
||||
|
||||
try {
|
||||
$shouldValidate = ['phone', 'role', 'first_name', 'last_name', 'password'];
|
||||
foreach ($shouldValidate as $value) {
|
||||
$exist = request()->input($value);
|
||||
if ($exist == null) {
|
||||
return response()->json([
|
||||
"message" => "incomplete data",
|
||||
"field" => $value
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
// Handle file uploads
|
||||
$profileImagePath = null;
|
||||
$idImagePath = null;
|
||||
|
||||
if ($request->hasFile('profile_image')) {
|
||||
$profileImagePath = $request->file('profile_image')->store('profiles', 'public');
|
||||
}
|
||||
|
||||
if ($request->hasFile('id_image')) {
|
||||
$idImagePath = $request->file('id_image')->store('ids', 'public');
|
||||
}
|
||||
|
||||
// Create user
|
||||
$user = User::create([
|
||||
'phone' => $request->phone,
|
||||
'role' => $request->role,
|
||||
'first_name' => $request->first_name,
|
||||
'last_name' => $request->last_name,
|
||||
'birth_date' => $request->birth_date,
|
||||
'profile_image' => $profileImagePath,
|
||||
'id_image' => $idImagePath,
|
||||
'password' => Hash::make($request->password),
|
||||
// is_approved defaults to false automatically
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Registration successful. Waiting for admin approval.',
|
||||
'user' => [
|
||||
'id' => $user->id,
|
||||
'phone' => $user->phone,
|
||||
'full_name' => $user->full_name,
|
||||
'role' => $user->role,
|
||||
]
|
||||
], 201);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'message' => 'Registration failed',
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function login(Request $request)
|
||||
{
|
||||
// Basic validation for login
|
||||
|
||||
$request->validate([
|
||||
'phone' => 'required',
|
||||
'password' => 'required'
|
||||
]);
|
||||
|
||||
try {
|
||||
// Find user by phone
|
||||
$user = User::where('phone', $request->phone)->first();
|
||||
|
||||
// Check if user exists and password is correct
|
||||
if (!$user || !Hash::check($request->password, $user->password)) {
|
||||
return response()->json([
|
||||
'message' => 'Invalid credentials'
|
||||
], 401);
|
||||
}
|
||||
|
||||
// Check if user is approved
|
||||
if (!$user->is_approved) {
|
||||
return response()->json([
|
||||
'message' => 'Account pending admin approval. Please wait for approval.'
|
||||
], 403);
|
||||
}
|
||||
|
||||
// Create API token
|
||||
$token = $user->createToken('auth-token')->plainTextToken;
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Login successful',
|
||||
'token' => $token,
|
||||
'user' => [
|
||||
'id' => $user->id,
|
||||
'phone' => $user->phone,
|
||||
'full_name' => $user->full_name,
|
||||
'role' => $user->role,
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $exc) {
|
||||
return response()->json([
|
||||
"message" => "failed!",
|
||||
"errors" => $exc->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function logout(Request $request)
|
||||
{
|
||||
// Delete the current access token
|
||||
$request->user()->currentAccessToken()->delete();
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Logged out successfully'
|
||||
]);
|
||||
}
|
||||
}
|
||||
48
app/Http/Requests/RegisterUserRequest.php
Normal file
48
app/Http/Requests/RegisterUserRequest.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class RegisterUserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true; // Allow all users to register
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'phone' => 'required|unique:users|regex:/^[0-9]{10,15}$/',
|
||||
'role' => 'required|in:tenant,owner',
|
||||
'first_name' => 'required|string|max:255',
|
||||
'last_name' => 'required|string|max:255',
|
||||
'birth_date' => 'required|date|before:-18 years',
|
||||
'profile_image' => 'nullable|image|max:2048', // 2MB max
|
||||
'id_image' => 'required|image|max:2048',
|
||||
'password' => 'required|min:8|confirmed',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom error messages for validator errors.
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'birth_date.before' => 'You must be at least 18 years old to register.',
|
||||
'phone.regex' => 'Phone number must be between 10-15 digits.',
|
||||
'id_image.required' => 'ID image is required for verification.',
|
||||
'phone.unique' => 'This phone number is already registered.',
|
||||
];
|
||||
}
|
||||
}
|
||||
المرجع في مشكلة جديدة
حظر مستخدم