diff --git a/lib/mixer_web/live/magic_sign_in_live.ex b/lib/mixer_web/live/magic_sign_in_live.ex
index 8be8ae8..ebc0b46 100644
--- a/lib/mixer_web/live/magic_sign_in_live.ex
+++ b/lib/mixer_web/live/magic_sign_in_live.ex
@@ -42,6 +42,7 @@ defmodule MixerWeb.MagicSignInLive do
form =
resource
|> Form.for_action(strategy.sign_in_action_name,
+ params: %{"token" => token},
domain: domain,
as: subject_name |> to_string(),
id: "#{subject_name}-#{strategy_name}-sign-in-form" |> slugify(),
@@ -98,7 +99,7 @@ defmodule MixerWeb.MagicSignInLive do
}
method="POST"
>
- {hidden_input(form, :token, value: @token)}
+ {hidden_input(form, :token, [])}
<%!-- Username field — only shown for new or username-less users --%>
@@ -172,8 +173,10 @@ defmodule MixerWeb.MagicSignInLive do
defp needs_username?(token, resource) do
with {:ok, claims} <- AshAuthentication.Jwt.peek(token),
- subject when is_binary(subject) <- Map.get(claims, "sub"),
- {:ok, user} <- AshAuthentication.subject_to_user(subject, resource) do
+ # 1. Try to find an existing user from the claims
+ user <- find_user(claims, resource),
+ # 2. If a user exists, check if they already have a username
+ false <- is_nil(user) do
is_nil(user.username)
else
_ ->
@@ -181,4 +184,30 @@ defmodule MixerWeb.MagicSignInLive do
true
end
end
+
+ defp find_user(claims, resource) do
+ # Try 'sub' first if it looks like a user subject (e.g. "User:123")
+ sub = Map.get(claims, "sub")
+
+ user =
+ if is_binary(sub) and String.contains?(sub, ":") do
+ case AshAuthentication.subject_to_user(sub, resource) do
+ {:ok, user} -> user
+ _ -> nil
+ end
+ end
+
+ # If not found via subject, try 'identity' (common in magic link tokens)
+ user ||
+ case Map.get(claims, "identity") || Map.get(claims, "email") do
+ email when is_binary(email) ->
+ case Ash.get(resource, [email: email], action: :get_by_email, authorize?: false) do
+ {:ok, user} -> user
+ _ -> nil
+ end
+
+ _ ->
+ nil
+ end
+ end
end