complete Complete User Request Submission section RAD-1
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace App\Services\Auth;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class AuthService
|
||||
{
|
||||
public function getLevelsForPhone(string $phone): array
|
||||
{
|
||||
session()->flush();
|
||||
$users = User::where('phone', $phone)->get(['level']);
|
||||
|
||||
return $users
|
||||
->map(fn($user) => match ($user->level) {
|
||||
'پزشک' => 'doctor',
|
||||
'سرپرست' => 'supervisor',
|
||||
'دانپزشک' => 'veterinarian',
|
||||
default => null,
|
||||
})
|
||||
->filter()
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
|
||||
public function authenticateByPhoneAndLevel(string $phone, string $level, string $password): ?User
|
||||
{
|
||||
$user = User::where('phone', $phone)
|
||||
->where('level', $level)
|
||||
->first();
|
||||
|
||||
if (! $user) return null;
|
||||
|
||||
if (! Hash::check($password, $user->password)) return null;
|
||||
|
||||
Auth::login($user);
|
||||
session()->regenerate();
|
||||
session()->forget('register_phone' , 'verified_phone' , 'otp_verified' , 'login_phone' , 'login_level' , 'available_levels');
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Auth;
|
||||
|
||||
use App\Models\OtpCode;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class OtpService
|
||||
{
|
||||
public function generateCode(): string
|
||||
{
|
||||
return (string) random_int(1000, 9999);
|
||||
}
|
||||
|
||||
public function sendForPhone(string $phone, int $minutes = 3): OtpCode
|
||||
{
|
||||
$code = $this->generateCode();
|
||||
$expiresAt = now()->addMinutes($minutes);
|
||||
|
||||
$otpCode = OtpCode::updateOrCreate(
|
||||
['phone' => $phone],
|
||||
['code' => $code, 'expires_at' => $expiresAt]
|
||||
);
|
||||
|
||||
$this->sendSms($phone, $code);
|
||||
|
||||
return $otpCode;
|
||||
}
|
||||
|
||||
public function verifyCode(string $phone, string $code): bool
|
||||
{
|
||||
$deleted = OtpCode::where('phone', $phone)
|
||||
->where('code', $code)
|
||||
->where('expires_at', '>', now())
|
||||
->delete();
|
||||
|
||||
return (bool) $deleted;
|
||||
}
|
||||
|
||||
public function existsValid(string $phone, string $code): bool
|
||||
{
|
||||
return OtpCode::where('phone', $phone)
|
||||
->where('code', $code)
|
||||
->where('expires_at', '>', now())
|
||||
->exists();
|
||||
}
|
||||
|
||||
private function sendSms(string $phone, string $code): array
|
||||
{
|
||||
try {
|
||||
$formattedRecipient = $this->formatPhoneForSms($phone);
|
||||
|
||||
$response = Http::withHeaders([
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
'Api-Key' => config('services.iranpayamak.api_key'),
|
||||
])
|
||||
->post(config('services.iranpayamak.api_url'), [
|
||||
'code' => config('services.iranpayamak.patterns.verify_code'),
|
||||
'attributes' => [
|
||||
'otp' => $code,
|
||||
'status' => 'بازنشانی رمز عبور'
|
||||
],
|
||||
'recipient' => $formattedRecipient,
|
||||
'line_number' => config('services.iranpayamak.line_number'),
|
||||
'number_format' => 'english',
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response->json();
|
||||
} else {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'message' => 'SMS sending failed: ' . $response->status(),
|
||||
'data' => $response->body()
|
||||
];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'message' => 'SMS sending exception: ' . $e->getMessage(),
|
||||
'data' => null
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function formatPhoneForSms(string $phone): string
|
||||
{
|
||||
if (str_starts_with($phone, '+98')) {
|
||||
return '0' . substr($phone, 3);
|
||||
}
|
||||
return $phone;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Auth;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RegistrationService
|
||||
{
|
||||
public function createUser(array $data): User
|
||||
{
|
||||
return DB::transaction(function () use ($data) {
|
||||
$user = User::create([
|
||||
'username' => 'rdl_'.Str::random(10),
|
||||
'phone' => $data['phone'],
|
||||
'email' => $data['email'] ?? null,
|
||||
'password' => Hash::make($data['password'] ?? Str::random(12)),
|
||||
'level' => $data['level'],
|
||||
'fullname' => $data['fullname'] ?? null,
|
||||
'national_code' => $data['national_code'] ?? null,
|
||||
'clinic_name' => $data['clinic_name'] ?? null,
|
||||
'clinic_phone' => $data['clinic_phone'] ?? null,
|
||||
'province' => $data['province'] ?? null,
|
||||
'city' => $data['city'] ?? null,
|
||||
'address' => $data['address'] ?? null,
|
||||
'specialty' => $data['specialty'] ?? null,
|
||||
]);
|
||||
|
||||
return $user;
|
||||
});
|
||||
}
|
||||
|
||||
public function registerAndLogin(array $data): Authenticatable
|
||||
{
|
||||
$user = $this->createUser($data);
|
||||
|
||||
Auth::login($user);
|
||||
session()->regenerate();
|
||||
session()->forget('register_phone' , 'verified_phone' , 'otp_verified' , 'login_phone' , 'login_level' , 'available_levels');
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user