Skip to content

Commit 4f8984d

Browse files
authored
fix: access token handling (#1512)
1 parent 5190510 commit 4f8984d

File tree

3 files changed

+64
-11
lines changed

3 files changed

+64
-11
lines changed

lib/realtime_web/channels/realtime_channel.ex

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -538,19 +538,15 @@ defmodule RealtimeWeb.RealtimeChannel do
538538
end
539539
end
540540

541-
defp assign_access_token(%{assigns: %{headers: headers}} = socket, params) do
541+
defp assign_access_token(%{assigns: %{tenant_token: tenant_token}} = socket, params) do
542542
access_token = Map.get(params, "access_token") || Map.get(params, "user_token")
543-
{_, header} = Enum.find(headers, {nil, nil}, fn {k, _} -> k == "x-api-key" end)
544543

545544
case access_token do
546-
nil -> assign(socket, :access_token, header)
547-
"sb_" <> _ -> assign(socket, :access_token, header)
545+
"sb_" <> _ -> assign(socket, :access_token, tenant_token)
548546
_ -> handle_access_token(socket, params)
549547
end
550548
end
551549

552-
defp assign_access_token(socket, params), do: handle_access_token(socket, params)
553-
554550
defp handle_access_token(%{assigns: %{tenant_token: _tenant_token}} = socket, %{"user_token" => user_token})
555551
when is_binary(user_token) do
556552
assign(socket, :access_token, user_token)

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Realtime.MixProject do
44
def project do
55
[
66
app: :realtime,
7-
version: "2.43.1",
7+
version: "2.43.2",
88
elixir: "~> 1.17.3",
99
elixirc_paths: elixirc_paths(Mix.env()),
1010
start_permanent: Mix.env() == :prod,

test/realtime_web/channels/realtime_channel_test.exs

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,13 +523,71 @@ defmodule RealtimeWeb.RealtimeChannelTest do
523523
end
524524

525525
describe "API Key validations" do
526-
test "api_key has not expired", %{tenant: tenant} do
526+
test "x-api-key header has not expired", %{tenant: tenant} do
527527
api_key = Generators.generate_jwt_token(tenant)
528528
{:ok, %Socket{} = socket} = connect(UserSocket, %{"log_level" => "warning"}, conn_opts(tenant, api_key))
529529

530530
assert {:ok, _, %Socket{}} = subscribe_and_join(socket, "realtime:test", %{})
531531
end
532532

533+
test "apikey param has not expired", %{tenant: tenant} do
534+
api_key = Generators.generate_jwt_token(tenant)
535+
536+
conn_opts = [
537+
connect_info: %{
538+
uri: URI.parse("https://#{tenant.external_id}.localhost:4000/socket/websocket"),
539+
x_headers: []
540+
}
541+
]
542+
543+
{:ok, %Socket{} = socket} = connect(UserSocket, %{"log_level" => "warning", "apikey" => api_key}, conn_opts)
544+
545+
assert {:ok, _, %Socket{} = socket} = subscribe_and_join(socket, "realtime:test", %{})
546+
assert socket.assigns.access_token == api_key
547+
end
548+
549+
test "join with access_token starting with sb_", %{tenant: tenant} do
550+
api_key = Generators.generate_jwt_token(tenant)
551+
{:ok, %Socket{} = socket} = connect(UserSocket, %{"log_level" => "warning"}, conn_opts(tenant, api_key))
552+
553+
assert {:ok, _, %Socket{} = socket} =
554+
subscribe_and_join(socket, "realtime:test", %{"access_token" => "sb_something"})
555+
556+
assert socket.assigns.access_token == api_key
557+
end
558+
559+
test "join with user_token starting with sb_", %{tenant: tenant} do
560+
api_key = Generators.generate_jwt_token(tenant)
561+
{:ok, %Socket{} = socket} = connect(UserSocket, %{"log_level" => "warning"}, conn_opts(tenant, api_key))
562+
563+
assert {:ok, _, %Socket{} = socket} =
564+
subscribe_and_join(socket, "realtime:test", %{"user_token" => "sb_something"})
565+
566+
assert socket.assigns.access_token == api_key
567+
end
568+
569+
test "join with access_token", %{tenant: tenant} do
570+
api_key = Generators.generate_jwt_token(tenant)
571+
access_token = Generators.generate_jwt_token(tenant)
572+
{:ok, %Socket{} = socket} = connect(UserSocket, %{"log_level" => "warning"}, conn_opts(tenant, api_key))
573+
574+
assert {:ok, _, %Socket{} = socket} =
575+
subscribe_and_join(socket, "realtime:test", %{"access_token" => access_token})
576+
577+
assert socket.assigns.access_token == access_token
578+
end
579+
580+
test "join with user_token", %{tenant: tenant} do
581+
api_key = Generators.generate_jwt_token(tenant)
582+
user_token = Generators.generate_jwt_token(tenant)
583+
{:ok, %Socket{} = socket} = connect(UserSocket, %{"log_level" => "warning"}, conn_opts(tenant, api_key))
584+
585+
assert {:ok, _, %Socket{} = socket} =
586+
subscribe_and_join(socket, "realtime:test", %{"user_token" => user_token})
587+
588+
assert socket.assigns.access_token == user_token
589+
end
590+
533591
test "api_key has expired", %{tenant: tenant} do
534592
assert capture_log(fn ->
535593
api_key =
@@ -688,13 +746,12 @@ defmodule RealtimeWeb.RealtimeChannelTest do
688746
assert [{_, ^transport_pid_1}] = Registry.lookup(RealtimeWeb.SocketDisconnect.Registry, tenant.external_id)
689747
end
690748

691-
defp conn_opts(tenant, token, params \\ %{}) do
749+
defp conn_opts(tenant, token) do
692750
[
693751
connect_info: %{
694752
uri: URI.parse("https://#{tenant.external_id}.localhost:4000/socket/websocket"),
695753
x_headers: [{"x-api-key", token}]
696-
},
697-
params: params
754+
}
698755
]
699756
end
700757

0 commit comments

Comments
 (0)