validate(['email' => 'required|email', 'password' => 'required|string', 'device_name' => 'nullable|string|max:100']); $user = User::where('email', strtolower($data['email']))->first(); if (!$user || !Hash::check($data['password'], $user->password)) { return response()->json(['message' => 'Email atau kata sandi tidak sesuai.'], 422); } $plain = Str::random(80); ApiToken::create([ 'user_id' => $user->id, 'name' => $data['device_name'] ?? 'Android', 'token_hash' => hash('sha256', $plain), 'expires_at' => now()->addDays(90), ]); return response()->json(['token' => $plain, 'token_type' => 'Bearer', 'user' => $this->userPayload($user)]); } public function me(Request $request) { return response()->json(['user' => $this->userPayload($request->user())]); } public function logout(Request $request) { $request->attributes->get('api_token')?->delete(); return response()->json(['message' => 'Sesi berhasil diakhiri.']); } private function userPayload(User $user): array { return ['id'=>$user->id,'name'=>$user->name,'email'=>$user->email,'role'=>$user->roleModel?->name ?? $user->getRawOriginal('role')]; } }