150 خطوط
4.7 KiB
PHP
150 خطوط
4.7 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Api;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Models\User;
|
||
use App\Services\ActivityLogger;
|
||
use App\Support\PasswordPolicy;
|
||
use Illuminate\Http\JsonResponse;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Facades\Auth;
|
||
use Illuminate\Support\Facades\Hash;
|
||
use Illuminate\Validation\ValidationException;
|
||
|
||
class AuthController extends Controller
|
||
{
|
||
public function login(Request $request): JsonResponse
|
||
{
|
||
$request->validate([
|
||
'phone' => 'required|string',
|
||
'password' => 'required',
|
||
]);
|
||
|
||
$login = $this->normalizeLoginIdentifier($request->phone);
|
||
$user = str_contains($login, '@')
|
||
? User::whereRaw('lower(email) = ?', [$login])->first()
|
||
: User::get()->first(fn (User $candidate) => $this->normalizeLoginIdentifier($candidate->phone) === $login);
|
||
|
||
if (! $user || ! Hash::check($request->password, $user->password)) {
|
||
throw ValidationException::withMessages([
|
||
'phone' => ['شماره موبایل یا رمز عبور اشتباه است'],
|
||
]);
|
||
}
|
||
|
||
if (! $user->is_active) {
|
||
return response()->json(['message' => 'حساب کاربری شما غیرفعال است'], 403);
|
||
}
|
||
|
||
Auth::guard('web')->login($user);
|
||
$request->session()->regenerate();
|
||
|
||
$user->update([
|
||
'last_login_at' => now(),
|
||
'last_login_ip' => $request->ip(),
|
||
'current_login_at' => now(),
|
||
]);
|
||
|
||
ActivityLogger::log('login', "User {$user->phone} logged in");
|
||
|
||
$user->load('roles.permissions', 'teams');
|
||
|
||
return response()->json([
|
||
'data' => $user,
|
||
]);
|
||
}
|
||
|
||
public function logout(Request $request): JsonResponse
|
||
{
|
||
$user = $request->user();
|
||
|
||
if ($user?->current_login_at) {
|
||
$user->increment('total_presence_seconds', max(0, $user->current_login_at->diffInSeconds(now())));
|
||
$user->forceFill([
|
||
'current_login_at' => null,
|
||
'last_logout_at' => now(),
|
||
])->save();
|
||
}
|
||
|
||
ActivityLogger::log('logout', 'User logged out');
|
||
|
||
Auth::guard('web')->logout();
|
||
if ($request->hasSession()) {
|
||
$request->session()->invalidate();
|
||
$request->session()->regenerateToken();
|
||
}
|
||
|
||
return response()->json(['message' => 'خروج با موفقیت انجام شد']);
|
||
}
|
||
|
||
public function me(Request $request): JsonResponse
|
||
{
|
||
$user = Auth::guard('web')->user();
|
||
|
||
if (! $user) {
|
||
return response()->json([
|
||
'authenticated' => false,
|
||
'data' => null,
|
||
]);
|
||
}
|
||
|
||
$user->load('roles.permissions', 'teams');
|
||
$user->permissions = $user->getAllPermissions()->pluck('name');
|
||
|
||
return response()->json([
|
||
'authenticated' => true,
|
||
'data' => $user,
|
||
]);
|
||
}
|
||
|
||
public function updateProfile(Request $request): JsonResponse
|
||
{
|
||
$user = $request->user();
|
||
|
||
$validated = $request->validate([
|
||
'name' => 'required|string|max:255',
|
||
'email' => 'required|email|unique:users,email,'.$user->id,
|
||
'phone' => 'nullable|string|max:20|unique:users,phone,'.$user->id,
|
||
'password' => ['nullable', ...PasswordPolicy::rules()],
|
||
'avatar' => 'nullable|image|mimes:jpg,jpeg,png,webp|max:2048',
|
||
]);
|
||
|
||
if ($request->hasFile('avatar')) {
|
||
$path = $request->file('avatar')->store('avatars', 'public');
|
||
$validated['avatar'] = $path;
|
||
}
|
||
|
||
if (! empty($validated['password'])) {
|
||
$validated['password'] = Hash::make($validated['password']);
|
||
} else {
|
||
unset($validated['password']);
|
||
}
|
||
|
||
$user->update($validated);
|
||
$user->load('roles.permissions', 'teams');
|
||
$user->permissions = $user->getAllPermissions()->pluck('name');
|
||
|
||
ActivityLogger::log('profile_updated', "User {$user->phone} updated profile");
|
||
|
||
return response()->json(['data' => $user]);
|
||
}
|
||
|
||
private function normalizeLoginIdentifier(?string $value): string
|
||
{
|
||
$value = trim((string) $value);
|
||
|
||
if (str_contains($value, '@')) {
|
||
return strtolower($value);
|
||
}
|
||
|
||
$value = strtr($value, [
|
||
'۰' => '0', '۱' => '1', '۲' => '2', '۳' => '3', '۴' => '4',
|
||
'۵' => '5', '۶' => '6', '۷' => '7', '۸' => '8', '۹' => '9',
|
||
'٠' => '0', '١' => '1', '٢' => '2', '٣' => '3', '٤' => '4',
|
||
'٥' => '5', '٦' => '6', '٧' => '7', '٨' => '8', '٩' => '9',
|
||
]);
|
||
|
||
return preg_replace('/\D+/', '', $value) ?? '';
|
||
}
|
||
}
|