credentials(); /** @var User|null $user */ $user = User::query()->when( isset($credentials['email']), fn ($query) => $query->where('email', $credentials['email']), fn ($query) => $query->where('username', $credentials['username'] ?? null) )->first(); if (! $user || ! Hash::check($credentials['password'], (string) $user->password)) { throw ValidationException::withMessages([ 'login' => [trans('auth.failed')], ]); } if (! in_array($user->role, ['tenant_admin', 'super_admin'], true)) { throw ValidationException::withMessages([ 'login' => [trans('auth.not_authorized')], ]); } if ($user->email_verified_at === null) { throw ValidationException::withMessages([ 'login' => [trans('auth.unverified')], ]); } [$token, $abilities] = $this->issueTokenFor($user); return response()->json([ 'token' => $token, 'token_type' => 'Bearer', 'abilities' => $abilities, 'user' => [ 'id' => $user->id, 'email' => $user->email, 'name' => $user->name, 'role' => $user->role, 'tenant_id' => $user->tenant_id, ], ]); } public function destroy(Request $request): JsonResponse { $user = $request->user(); $token = $user?->currentAccessToken(); if ($token) { $token->delete(); } return response()->json(['ok' => true]); } public function me(Request $request): JsonResponse { $user = $request->user(); /** @var Tenant|null $tenant */ $tenant = $request->attributes->get('tenant'); if (! $tenant && $user?->tenant_id) { $tenant = Tenant::query()->find($user->tenant_id); } $tenantPayload = null; if ($tenant) { $tenantPayload = [ 'id' => $tenant->id, 'tenant_id' => $tenant->id, 'name' => $tenant->name, 'slug' => $tenant->slug, 'event_credits_balance' => $tenant->event_credits_balance, 'features' => $tenant->features, ]; } return response()->json([ 'user' => $user ? Arr::only($user->toArray(), [ 'id', 'name', 'email', 'role', 'tenant_id', ]) : null, 'tenant' => $tenantPayload, 'abilities' => $user?->currentAccessToken()?->abilities ?? [], ]); } public function exchange(Request $request): JsonResponse { /** @var User|null $user */ $user = Auth::guard('web')->user(); if (! $user) { return response()->json([ 'error' => 'unauthenticated', 'message' => trans('auth.failed'), ], 401); } if (! in_array($user->role, ['tenant_admin', 'super_admin'], true)) { return response()->json([ 'error' => 'forbidden', 'message' => trans('auth.not_authorized'), ], 403); } if ($user->email_verified_at === null) { return response()->json([ 'error' => 'unverified', 'message' => trans('auth.unverified'), ], 422); } [$token, $abilities] = $this->issueTokenFor($user); return response()->json([ 'token' => $token, 'token_type' => 'Bearer', 'abilities' => $abilities, 'user' => [ 'id' => $user->id, 'email' => $user->email, 'name' => $user->name, 'role' => $user->role, 'tenant_id' => $user->tenant_id, ], ]); } /** * @return array */ private function resolveTokenAbilities(User $user): array { $abilities = ['tenant-admin']; if ($user->tenant_id) { $abilities[] = 'tenant:'.$user->tenant_id; } if ($user->role === 'super_admin') { $abilities[] = 'super-admin'; } return $abilities; } /** * @return array{0: string, 1: array} */ private function issueTokenFor(User $user): array { $user->tokens()->where('name', 'tenant-admin')->delete(); $abilities = $this->resolveTokenAbilities($user); $token = $user->createToken('tenant-admin', $abilities); return [$token->plainTextToken, $abilities]; } }