endpointId = (string) $endpoint->getKey(); $this->responseStatus = $endpoint->response_status; $this->responseHeadersJson = json_encode( $endpoint->response_headers ?? [], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES, ) ?: '{}'; $this->responseBody = $endpoint->response_body ?? '{}'; } /** * @return array */ public function getListeners(): array { $endpoint = $this->endpoint(); $prefix = $endpoint->is_public ? 'echo' : 'echo-private'; return [ $prefix.':webhooks.'.$this->endpointId.',.webhook.request.received' => 'requestReceived', ]; } /** * @param array $event */ public function requestReceived(array $event = []): void { if (($event['endpointId'] ?? null) === $this->endpointId) { $this->resetPage(); $requestId = $event['requestId'] ?? null; if (is_string($requestId) && $requestId !== '') { $this->dispatch( 'xhr-request-available', endpointId: $this->endpointId, requestId: $requestId, ); } } } public function updatedSearch(): void { $this->resetPage(); } public function updatedMethodFilter(): void { $this->resetPage(); } public function selectRequest(string $requestId): void { $webhookRequest = $this->endpoint()->requests()->findOrFail($requestId); Gate::authorize('view', $webhookRequest); $this->selectedRequestId = $webhookRequest->getKey(); } public function clearSelectedRequest(): void { $this->selectedRequestId = null; } /** * @return array{ * endpointId: string, * requestId: string, * method: string, * requestUri: string, * headers: array|string>, * body: string, * } */ public function xhrRequestPayload(string $requestId): array { $webhookRequest = $this->endpoint()->requests()->findOrFail($requestId); Gate::authorize('view', $webhookRequest); return [ 'endpointId' => (string) $this->endpointId, 'requestId' => (string) $webhookRequest->getKey(), 'method' => $webhookRequest->method, 'requestUri' => $webhookRequest->request_uri, 'headers' => $webhookRequest->headers ?? [], 'body' => base64_encode((string) ($webhookRequest->body ?? '')), ]; } public function deleteRequest(string $requestId, DeleteWebhookRequestAction $deleteWebhookRequest): void { $webhookRequest = $this->endpoint()->requests()->findOrFail($requestId); $deleteWebhookRequest->handle(Auth::user(), $webhookRequest); if ($this->selectedRequestId === $requestId) { $this->selectedRequestId = null; } } public function saveResponse(ConfigureWebhookEndpointAction $configureWebhookEndpoint): void { $this->validate([ 'responseStatus' => ['required', 'integer', 'between:100,599'], 'responseBody' => ['string'], 'responseHeadersJson' => ['required', 'json'], ]); $headers = json_decode($this->responseHeadersJson, true); if (! is_array($headers)) { throw ValidationException::withMessages([ 'responseHeadersJson' => 'Response headers must be a JSON object.', ]); } /** @var User|null $user */ $user = Auth::user(); $configureWebhookEndpoint->handle( $user, $this->endpoint(), $this->responseStatus, $headers, $this->responseBody, ); $this->responseSaved = true; } public function deleteEndpoint(): void { $endpoint = $this->endpoint(); Gate::authorize('delete', $endpoint); $endpoint->delete(); $this->redirectRoute('home'); } public function render(): View { $endpoint = $this->endpoint(); $requestQuery = $endpoint->requests() ->select(['id', 'method', 'request_uri', 'content_type', 'body_size', 'ip_address', 'received_at']) ->when($this->methodFilter !== 'ALL', fn ($query) => $query->where('method', $this->methodFilter)) ->when($this->search !== '', function ($query): void { $search = '%'.$this->search.'%'; $query->where(function ($query) use ($search): void { $query->where('request_uri', 'like', $search) ->orWhere('ip_address', 'like', $search) ->orWhere('user_agent', 'like', $search); }); }) ->latest('received_at'); $selectedRequest = null; if ($this->selectedRequestId !== null) { $selectedRequest = $endpoint->requests()->find($this->selectedRequestId); if ($selectedRequest instanceof WebhookRequest) { Gate::authorize('view', $selectedRequest); } } return view('livewire.inspector', [ 'endpoint' => $endpoint, 'webhookRequests' => $requestQuery->paginate((int) config('webhooks.page_size', 25)), 'selectedRequest' => $selectedRequest, ]); } private function endpoint(): WebhookEndpoint { $endpoint = WebhookEndpoint::query()->findOrFail($this->endpointId); Gate::authorize('view', $endpoint); return $endpoint; } }