- add absinthe_phoenix for WebSocket subscription support - create GraphQL WebSocket socket with API token auth at /socket/graphql - add time-series queries: deviceSensors, sensorReadings, interfaceTraffic, checkResults - add subscriptions: deviceStatusChanged, alertEvent, sensorReadingsUpdated - wire subscription triggers into agent_channel and alerts contexts - add org-scoped access control for sensors/interfaces via join queries - add 17 tests covering queries, org isolation, empty data edge cases, and auth - update GraphQL API docs page with time-series and subscription sections
32 lines
889 B
Elixir
32 lines
889 B
Elixir
defmodule ToweropsWeb.GraphQLSocket do
|
|
@moduledoc """
|
|
WebSocket endpoint for GraphQL subscriptions.
|
|
|
|
Authenticates via API token passed as a connection parameter.
|
|
"""
|
|
|
|
use Phoenix.Socket
|
|
use Absinthe.Phoenix.Socket, schema: ToweropsWeb.GraphQL.Schema
|
|
|
|
@impl true
|
|
def connect(%{"token" => token}, socket, _connect_info) when is_binary(token) do
|
|
case Towerops.ApiTokens.verify_token(token) do
|
|
{:ok, org_id, user} ->
|
|
socket =
|
|
socket
|
|
|> assign(:organization_id, org_id)
|
|
|> assign(:user, user)
|
|
|> Absinthe.Phoenix.Socket.put_options(context: %{organization_id: org_id, user: user})
|
|
|
|
{:ok, socket}
|
|
|
|
{:error, :invalid_token} ->
|
|
:error
|
|
end
|
|
end
|
|
|
|
def connect(_params, _socket, _connect_info), do: :error
|
|
|
|
@impl true
|
|
def id(socket), do: "graphql_socket:#{socket.assigns.organization_id}"
|
|
end
|