I have a homegrown invitation solution where admin users can invite other users. I did an experiment with using the magic link strategy, but my thinking is that I don't want to actually create the user record until the invitation is accepted.
The following Phoenix controller handles accepting an invitation:
defmodule DrengWeb.InvitationController do use DrengWeb, :controller def show(conn, %{"token" => token}) do case Dreng.Accounts.get_invitation_by_token(token) do {:ok, invitation} -> render(conn, :valid_invitation, token: token, role: invitation.role) {:error, _} -> conn |> put_status(404) |> render(:invalid_invitation) end end def create_user(conn, %{"token" => token}) do case Dreng.Accounts.accept_invitation(token) do {:ok, user} -> conn # log in here? |> assign(:current_user, user) |> redirect(to: ~p"/signup") {:error, _} -> conn |> put_flash(:error, "This invitation is not valid") |> redirect(to: ~p"/") end endend
defmodule DrengWeb.InvitationController do use DrengWeb, :controller def show(conn, %{"token" => token}) do case Dreng.Accounts.get_invitation_by_token(token) do {:ok, invitation} -> render(conn, :valid_invitation, token: token, role: invitation.role) {:error, _} -> conn |> put_status(404) |> render(:invalid_invitation) end end def create_user(conn, %{"token" => token}) do case Dreng.Accounts.accept_invitation(token) do {:ok, user} -> conn # log in here? |> assign(:current_user, user) |> redirect(to: ~p"/signup") {:error, _} -> conn |> put_flash(:error, "This invitation is not valid") |> redirect(to: ~p"/") end endend
The
Dreng.Accounts.accept_invitation
Dreng.Accounts.accept_invitation
is a create action on the
User
User
resource which validates the invitation token and creates a user.
I am probably missing something simple, but I'm not sure how to go about persisting the user to the session in a way that is compatiable with AshAuth? Is it possible without creating a new strategy?
Solution
This might a bit dirty, but by adding the
GenerateTokenChange
GenerateTokenChange
and borrowing the magic link signin strategy I got my action to work
create :sign_up_with_invitation do argument :token, :string, allow_nil?: false+ change {AshAuthentication.GenerateTokenChange, strategy_name: :magic_link_signin} change Dreng.Changes.ValidateInvitation end
create :sign_up_with_invitation do argument :token, :string, allow_nil?: false+ change {AshAuthentication.GenerateTokenChange, strategy_name: :magic_link_signin} change Dreng.Changes.ValidateInvitation end
The Elixir backend framework for unparalleled productivity. Declarative tools that let you stop wasting time. Use with Phoenix LiveView or build APIs in minutes for your front-end of choice.