create([ 'first_name' => $request->string('first_name')->toString(), 'last_name' => $request->string('last_name')->toString(), 'email' => $request->string('email')->toString(), 'phone' => $request->input('phone'), 'birthdate' => $request->input('birthdate'), 'password' => $request->string('password')->toString(), 'locale' => $request->input('locale', 'fr'), 'is_active' => true, ]); Wallet::query()->create([ 'user_id' => $user->id, 'currency' => 'EUR', 'current_balance' => 0, 'status' => 'active', ]); $tokens = $this->issueTokenPair($user, $request->input('device_name', 'mobile')); return $this->created([ 'user' => new UserResource($user), ...$tokens, ], 'Inscription réussie.'); } public function login(LoginRequest $request): JsonResponse { $user = User::query()->where('email', $request->string('email')->toString())->first(); if ($user === null || ! Hash::check($request->string('password')->toString(), $user->password)) { return $this->error('Identifiants invalides.', 401); } if (! $user->is_active) { return $this->error('Compte utilisateur désactivé.', 403); } $tokens = $this->issueTokenPair($user, $request->input('device_name', 'mobile')); return $this->success([ 'user' => new UserResource($user), ...$tokens, ], 'Connexion réussie.'); } public function refresh(RefreshRequest $request): JsonResponse { $token = PersonalAccessToken::findToken($request->string('refresh_token')->toString()); if ($token === null || ! $token->can('refresh') || ! $token->can('user')) { return $this->error('Refresh token invalide.', 401); } $user = $token->tokenable; if (! $user instanceof User || ! $user->is_active) { return $this->error('Utilisateur non autorisé.', 403); } $token->delete(); $user->tokens()->where('name', 'like', '%-access')->delete(); $tokens = $this->issueTokenPair($user, 'mobile'); return $this->success([ 'user' => new UserResource($user), ...$tokens, ], 'Token renouvelé.'); } public function logout(Request $request): JsonResponse { $request->user()?->currentAccessToken()?->delete(); return $this->success(message: 'Déconnexion réussie.'); } public function me(Request $request): JsonResponse { return $this->success([ 'user' => new UserResource($request->user()), ]); } private function issueTokenPair(User $user, string $deviceName): array { $accessMinutes = (int) config('laverie.auth.access_token_ttl_minutes', 60); $refreshDays = (int) config('laverie.auth.refresh_token_ttl_days', 30); $accessToken = $user->createToken( "{$deviceName}-access", ['user', 'access'], now()->addMinutes($accessMinutes), ); $refreshToken = $user->createToken( "{$deviceName}-refresh", ['user', 'refresh'], now()->addDays($refreshDays), ); return [ 'access_token' => $accessToken->plainTextToken, 'refresh_token' => $refreshToken->plainTextToken, 'token_type' => 'Bearer', 'expires_in' => $accessMinutes * 60, ]; } }