validate([ 'name' => 'required|string|max:100', 'username' => 'required|string|max:50|unique:users|alpha_dash', 'email' => 'required|email|unique:users', 'password' => 'required|string|min:6|confirmed', ]); $user = User::create([ 'name' => $data['name'], 'username' => $data['username'], 'email' => $data['email'], 'password' => $data['password'], 'role' => 'user', 'membership' => 'free', ]); $token = $user->createToken('animexe-app')->plainTextToken; return response()->json([ 'token' => $token, 'user' => $this->userResource($user), ], 201); } public function login(Request $request) { $data = $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); $user = User::where('email', $data['email'])->first(); if (!$user || !Hash::check($data['password'], $user->password)) { throw ValidationException::withMessages([ 'email' => ['E-posta veya şifre hatalı.'], ]); } if ($user->is_banned) { return response()->json([ 'message' => 'Hesabınız yasaklandı. Sebep: ' . ($user->ban_reason ?? 'Belirtilmedi'), ], 403); } $token = $user->createToken('animexe-app')->plainTextToken; return response()->json([ 'token' => $token, 'user' => $this->userResource($user), ]); } public function logout(Request $request) { $request->user()->currentAccessToken()->delete(); return response()->json(['message' => 'Çıkış yapıldı.']); } public function me(Request $request) { return response()->json(['user' => $this->userResource($request->user())]); } public function saveFcmToken(Request $request) { $data = $request->validate(['token' => 'required|string|max:500']); $request->user()->update(['fcm_token' => $data['token']]); return response()->json(['ok' => true]); } public function updateProfile(Request $request) { $user = $request->user(); $request->validate([ 'name' => 'sometimes|string|max:100', 'username' => 'sometimes|string|max:50|unique:users,username,' . $user->id . '|alpha_dash', 'password' => 'sometimes|string|min:6|confirmed', 'bio' => 'sometimes|nullable|string|max:300', 'website' => 'sometimes|nullable|string|max:100', 'twitter' => 'sometimes|nullable|string|max:50', 'instagram' => 'sometimes|nullable|string|max:50', 'discord' => 'sometimes|nullable|string|max:50', 'avatar' => 'sometimes|nullable|image|max:3072', 'banner' => 'sometimes|nullable|image|max:6144', ]); $data = $request->only(['name', 'username', 'bio', 'website', 'twitter', 'instagram', 'discord']); $data = array_filter($data, fn($v) => $v !== null); if ($request->filled('password')) { $data['password'] = bcrypt($request->input('password')); } if ($request->hasFile('avatar')) { $data['avatar'] = $request->file('avatar')->store('avatars', 'public'); } if ($request->hasFile('banner')) { $data['banner_image'] = $request->file('banner')->store('banners', 'public'); } if (!empty($data)) { $user->update($data); } return response()->json(['user' => $this->userResource($user->fresh())]); } private function userResource(User $user): array { return [ 'id' => $user->id, 'name' => $user->name, 'username' => $user->username, 'email' => $user->email, 'bio' => $user->bio, 'website' => $user->website, 'twitter' => $user->twitter, 'instagram' => $user->instagram, 'discord' => $user->discord, 'avatar' => $user->avatar ? (\App\Support\MediaUrl::fromStoragePath($user->avatar)) : null, 'banner_image' => $user->banner_image ? (\App\Support\MediaUrl::fromStoragePath($user->banner_image)) : null, 'role' => $user->role, 'membership' => $user->membership, 'is_premium' => $user->isPremium(), 'premium_expires_at' => $user->premium_expires_at?->toISOString(), 'created_at' => $user->created_at?->toISOString(), ]; } }