1013 B · text History bfa2c00
defmodule DiogramosWeb.UserSocket do
  @moduledoc """
  Token-authenticated Phoenix socket for native clients.

  Connects with `?token=<api-token>` — the same bearer the HTTP API uses.
  On success we assign `:user_id` so channels can scope themselves without
  repeating the DB hit.

  The socket id is per-user, so revoking any one of a user's API tokens
  disconnects all of that user's sockets. See
  `Diogramos.Accounts.delete_api_token/2` for why that trade-off was taken.
  """
  use Phoenix.Socket

  alias Diogramos.Accounts

  channel "canvas:*", DiogramosWeb.CanvasChannel

  @impl true
  def connect(%{"token" => token}, socket, _connect_info) when is_binary(token) do
    case Accounts.fetch_user_by_api_token(token) do
      {user, _token_id} -> {:ok, assign(socket, :user_id, user.id)}
      _ -> :error
    end
  end

  def connect(_params, _socket, _connect_info), do: :error

  @impl true
  def id(%{assigns: %{user_id: user_id}}), do: "user_socket:#{user_id}"
  def id(_socket), do: nil
end