validated(); $avatarPath = null; if ($request->hasFile('avatar')) { $avatarPath = $request->file('avatar')->store('avatars', 'public'); } $user = User::create([ 'name' => $data['name'], 'email' => strtolower($data['email']), 'password' => Hash::make($data['password']), 'avatar_url' => $avatarPath, ]); $token = $user->createToken('api', ['user'])->plainTextToken; return response()->json([ 'user' => new UserResource($user), ], 201)->cookie('token', $token, 60 * 24 * 30); } public function login(LoginRequest $request): JsonResponse { $data = $request->validated(); $user = User::where('email', strtolower($data['email']))->first(); if (! $user || ! Hash::check($data['password'], $user->password)) { return response()->json([ 'message' => 'Identifiants invalides', ], 401); } $token = $user->createToken('api')->plainTextToken; return response()->json([ 'user' => new UserResource($user), ])->cookie('token', $token, 60 * 24 * 30); } public function logout(): JsonResponse { $request = request(); $request->user()->currentAccessToken()->delete(); return response()->json([ 'message' => 'Déconnecté avec succès', ])->withoutCookie('token'); } public function me(): JsonResource|JsonResponse { $user = auth()->user(); if (! $user) { return response()->json(['message' => 'Non authentifié'], 401); } return new UserResource($user); } public function update(UpdateUserRequest $request): JsonResource { $user = $request->user(); $data = $request->validated(); $nutritionGoals = $data['nutritionGoals'] ?? null; if ($request->hasFile('avatar')) { if ($user->avatar_url) { Storage::disk('public')->delete($user->avatar_url); } $path = $request->file('avatar')->store('avatars', 'public'); $data['avatar_url'] = $path; } unset($data['avatar']); unset($data['nutritionGoals']); if (is_array($nutritionGoals)) { $data['daily_calorie_goal'] = $nutritionGoals['calories']; $data['daily_protein_goal'] = $nutritionGoals['proteins']; $data['daily_carbs_goal'] = $nutritionGoals['carbs']; $data['daily_fats_goal'] = $nutritionGoals['fats']; } if (! empty($data)) { $user->update($data); } return new UserResource($user->fresh()); } public function destroy(Request $request): JsonResponse { $user = $request->user(); $storagePaths = collect([$user->avatar_url]) ->merge($user->mealPosts()->withTrashed()->pluck('image_url')) ->filter(fn (?string $path): bool => $this->isPublicStoragePath($path)) ->values() ->all(); DB::transaction(function () use ($user): void { $user->tokens()->delete(); $user->notifications()->delete(); DB::table('sessions') ->where('user_id', $user->getKey()) ->delete(); DB::table('password_reset_tokens') ->where('email', $user->email) ->delete(); $user->delete(); }); if (! empty($storagePaths)) { Storage::disk('public')->delete($storagePaths); } return response()->json([ 'message' => 'Compte supprimé avec succès', ])->withoutCookie('token'); } private function isPublicStoragePath(?string $path): bool { return filled($path) && ! Str::startsWith($path, ['http://', 'https://']); } }