108 lines
3.4 KiB
PHP
108 lines
3.4 KiB
PHP
<?php
|
|
namespace App\Services;
|
|
|
|
use App\Models\Outlet;
|
|
use App\Models\Tenant;
|
|
use App\Models\User;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
use Illuminate\Support\Str;
|
|
|
|
class AuthService
|
|
{
|
|
public function login(array $data, string $ip)
|
|
{
|
|
$identifier = $data['identifier'];
|
|
$businessCode = $data['business_code'] ?? null;
|
|
$throttleKey = Str::lower($identifier) . '|' . $ip;
|
|
|
|
if (RateLimiter::tooManyAttempts($throttleKey, 6)) {
|
|
$seconds = RateLimiter::availableIn($throttleKey);
|
|
return [
|
|
'error' => 'lockout',
|
|
'seconds' => $seconds,
|
|
'until' => now()->addSeconds($seconds)->toIso8601String(),
|
|
];
|
|
}
|
|
|
|
$query = User::withoutGlobalScopes();
|
|
|
|
if ($businessCode) {
|
|
$tenant = Tenant::where('business_code', '=', $businessCode)->first();
|
|
|
|
if(!$tenant) {
|
|
return ['error' => 'invalid_business_code'];
|
|
}
|
|
|
|
$query->where('tenant_id', '=', $tenant->uuid);
|
|
}
|
|
|
|
$loginField = filter_var($identifier, FILTER_VALIDATE_EMAIL) ? 'email' : 'phone_number';
|
|
|
|
$user = $query->where($loginField, $identifier)->first();
|
|
|
|
$storedHash = $user->password;
|
|
|
|
if (str_starts_with($storedHash, '$2a$')) {
|
|
$storedHash = str_replace('$2a$', '$2y$', $storedHash);
|
|
}
|
|
|
|
if (!$user || !Hash::check($data['password'], $storedHash)) {
|
|
RateLimiter::hit($throttleKey, 3600);
|
|
return ['error' => 'invalid_credentials'];
|
|
}
|
|
|
|
if ($user->role === 'owner') {
|
|
$user->load(['tenant.outlets', 'tenant.users']);
|
|
} else {
|
|
$user->load(['tenant', 'outlet']);
|
|
}
|
|
|
|
RateLimiter::clear($throttleKey);
|
|
$user->tokens()->delete(); // logout dari device lain
|
|
|
|
return [
|
|
'token' => $user->createToken('UserAuthToken')->plainTextToken,
|
|
'user' => $user,
|
|
];
|
|
}
|
|
|
|
public function register(array $data)
|
|
{
|
|
return DB::transaction(function () use ($data) {
|
|
$tenant = Tenant::create([
|
|
'uuid' => (string) Str::uuid7(),
|
|
'business_name' => $data['business_name'],
|
|
'business_code' => $data['business_code'],
|
|
'subscription_level' => 'standart',
|
|
]);
|
|
|
|
$outlet = Outlet::create([
|
|
'uuid' => (string) Str::uuid7(),
|
|
'tenant_id' => $tenant->uuid,
|
|
'name' => $data['business_name'],
|
|
'is_main_outlet' => true,
|
|
]);
|
|
|
|
$user = User::create([
|
|
'uuid' => (string) Str::uuid7(),
|
|
'tenant_id' => $tenant->uuid,
|
|
'outlet_id' => $outlet->uuid,
|
|
'name' => $data['name'],
|
|
'phone_number' => $data['phone_number'],
|
|
'email' => $data['email'],
|
|
'password' => Hash::make($data['password']),
|
|
'role' => 'owner',
|
|
'is_active' => true,
|
|
'last_sync' => Carbon::now()
|
|
]);
|
|
|
|
return [
|
|
'business_code' => $tenant->business_code,
|
|
'user' => $user,
|
|
];
|
|
});
|
|
}
|
|
} |