Files
firezone/elixir/apps/api/lib/api/client/socket.ex
Jamil 17d7e29b81 fix(portal): use public key for TURN creds (#9870)
As a followup to #9856, after talking with @bmanifold, we determined
using the public_key as the username for TURN credentials is a safer bet
because:

- It's by definition public and therefore does not need to be obfuscated
- It's shorter-lived than the token, especially for the gateway
- It essentially represents the data plane connection for client/gateway
and naturally rotates along with the key state for those
2025-07-15 01:48:02 +00:00

59 lines
1.8 KiB
Elixir

defmodule API.Client.Socket do
use Phoenix.Socket
alias Domain.{Auth, Tokens, Clients}
require Logger
require OpenTelemetry.Tracer
## Channels
channel "client", API.Client.Channel
## Authentication
@impl true
def connect(%{"token" => token} = attrs, socket, connect_info) do
:otel_propagator_text_map.extract(connect_info.trace_context_headers)
OpenTelemetry.Tracer.with_span "client.connect" do
context = API.Sockets.auth_context(connect_info, :client)
with {:ok, subject} <- Auth.authenticate(token, context),
{:ok, client} <- Clients.upsert_client(attrs, subject) do
OpenTelemetry.Tracer.set_attributes(%{
token_id: subject.token_id,
client_id: client.id,
lat: client.last_seen_remote_ip_location_lat,
lon: client.last_seen_remote_ip_location_lon,
version: client.last_seen_version,
account_id: subject.account.id
})
socket =
socket
|> assign(:subject, subject)
|> assign(:client, client)
|> assign(:opentelemetry_span_ctx, OpenTelemetry.Tracer.current_span_ctx())
|> assign(:opentelemetry_ctx, OpenTelemetry.Ctx.get_current())
{:ok, socket}
else
{:error, :unauthorized} ->
OpenTelemetry.Tracer.set_status(:error, "unauthorized")
{:error, :invalid_token}
{:error, reason} ->
OpenTelemetry.Tracer.set_status(:error, inspect(reason))
Logger.debug("Error connecting client websocket: #{inspect(reason)}")
{:error, reason}
end
end
end
def connect(_params, _socket, _connect_info) do
{:error, :missing_token}
end
@impl true
def id(socket), do: Tokens.socket_id(socket.assigns.subject.token_id)
end