validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'email', 'max:255', 'unique:users,email'], 'password' => ['required', 'confirmed', Password::defaults()], ]); $user = User::create($data); $token = $user->createToken('api')->plainTextToken; return response()->json(['token' => $token, 'user' => $user], 201); } public function login(Request $request): JsonResponse { $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required', 'string'], ]); if (! Auth::attempt($credentials)) { return response()->json(['message' => 'Invalid credentials.'], 401); } /** @var User $user */ $user = Auth::user(); $token = $user->createToken('api')->plainTextToken; return response()->json(['token' => $token, 'user' => $user]); } public function logout(Request $request): JsonResponse { $token = $request->user()->currentAccessToken(); // TransientToken means session-based auth (no Bearer token) — invalidate session instead if ($token instanceof TransientToken) { $request->session()->invalidate(); $request->session()->regenerateToken(); } else { $token->delete(); } return response()->json(['message' => 'Logged out.']); } public function me(Request $request): JsonResponse { $user = $request->user(); $subscription = $user->subscription(); $expiresAt = $subscription?->ends_at ?? $subscription?->current_period_end; return response()->json(array_merge( $user->toArray(), [ 'tier' => PlanFeatures::for($user)->tier(), 'subscription_cancelled' => $subscription?->canceled() ?? false, 'subscription_cadence' => Plan::resolveCadenceForUser($user), 'subscribed_at' => $subscription?->created_at?->toIso8601String(), 'subscription_expires_at' => $expiresAt?->toIso8601String(), ], )); } }