diff --git a/lib/mv_web/live/auth/link_oidc_account_live.ex b/lib/mv_web/live/auth/link_oidc_account_live.ex index 05faf67..325a2fd 100644 --- a/lib/mv_web/live/auth/link_oidc_account_live.ex +++ b/lib/mv_web/live/auth/link_oidc_account_live.ex @@ -20,10 +20,13 @@ defmodule MvWeb.LinkOidcAccountLive do @impl true def mount(_params, session, socket) do + # Use SystemActor for authorization during OIDC linking (user is not yet logged in) + system_actor = Mv.Helpers.SystemActor.get_system_actor() + with user_id when not is_nil(user_id) <- Map.get(session, "oidc_linking_user_id"), oidc_user_info when not is_nil(oidc_user_info) <- Map.get(session, "oidc_linking_user_info"), - {:ok, user} <- Ash.get(Mv.Accounts.User, user_id) do + {:ok, user} <- Ash.get(Mv.Accounts.User, user_id, actor: system_actor) do # Check if user is passwordless if passwordless?(user) do # Auto-link passwordless user immediately @@ -46,9 +49,12 @@ defmodule MvWeb.LinkOidcAccountLive do end defp reload_user!(user_id) do + # Use SystemActor for authorization during OIDC linking (user is not yet logged in) + system_actor = Mv.Helpers.SystemActor.get_system_actor() + Mv.Accounts.User |> Ash.Query.filter(id == ^user_id) - |> Ash.read_one!() + |> Ash.read_one!(actor: system_actor) end defp reset_password_form(socket) do @@ -58,13 +64,16 @@ defmodule MvWeb.LinkOidcAccountLive do defp auto_link_passwordless_user(socket, user, oidc_user_info) do oidc_id = Map.get(oidc_user_info, "sub") || Map.get(oidc_user_info, "id") + # Use SystemActor for authorization (passwordless user auto-linking) + system_actor = Mv.Helpers.SystemActor.get_system_actor() + case user.id |> reload_user!() |> Ash.Changeset.for_update(:link_oidc_id, %{ oidc_id: oidc_id, oidc_user_info: oidc_user_info }) - |> Ash.update() do + |> Ash.update(actor: system_actor) do {:ok, updated_user} -> Logger.info( "Passwordless account auto-linked to OIDC: user_id=#{updated_user.id}, oidc_id=#{oidc_id}" @@ -187,6 +196,9 @@ defmodule MvWeb.LinkOidcAccountLive do defp link_oidc_account(socket, user, oidc_user_info) do oidc_id = Map.get(oidc_user_info, "sub") || Map.get(oidc_user_info, "id") + # Use SystemActor for authorization (user just verified password but is not yet logged in) + system_actor = Mv.Helpers.SystemActor.get_system_actor() + # Update the user with the OIDC ID case user.id |> reload_user!() @@ -194,7 +206,7 @@ defmodule MvWeb.LinkOidcAccountLive do oidc_id: oidc_id, oidc_user_info: oidc_user_info }) - |> Ash.update() do + |> Ash.update(actor: system_actor) do {:ok, updated_user} -> # After successful linking, redirect to OIDC login # Since the user now has an oidc_id, the next OIDC login will succeed