Can the confirmation email be manually re-sent in ash_authentication?

Hey @zachdaniel :waving_hand:

Wondering if there has been any official work on this feature since the OP.

I just went through upgrading to require email verification (before access) and in the course of it, ran into the same problem.

Here’s the solution I came up with. If it’s in any way sketch I’d appreciate the feedback (or a pointer to a more official implementation)!

First off, in my router.ex I just added a post action to handle a “send verification again” link:

    post "/resend-confirmation", PageController, :resend_confirmation

Then, implemented the following function on my PageController:

  alias AshAuthentication.AddOn.Confirmation
  alias WasteWalk.Accounts.User
  alias User.Senders.SendNewUserConfirmationEmail

  def resend_confirmation(conn, _params) do
    user = conn.assigns[:current_user]

    cond do
      is_nil(user) ->
        conn |> put_flash(:error, "You must be signed in to resend a verification email.") |> redirect(to: ~p"/sign-in")

      user.confirmed_at != nil ->
        conn |> put_flash(:info, "Your email is already verified.") |> redirect(to: ~p"/")

      true ->
        strategy = AshAuthentication.Info.strategy!(User, :confirm_new_user)
        changeset = Ash.Changeset.new(user)
        {:ok, token} = Confirmation.confirmation_token(strategy, changeset, user)
        SendNewUserConfirmationEmail.send(user, token, [])
        conn |> put_flash(:info, "Verification email sent. Please check your inbox.") |> redirect(to: ~p"/")
    end
  end

And… it seems to work fine. :slight_smile:

The bit about is_nil(user) being redirected to sign in is, I think, a solid security approach. Basically, the workflow ends up being:

  1. First time user signs up, lands on home page, we send verification email. User is technically authenticated (we know the user token) but, they aren’t verified yet (user.confirmed == nil). In my app, they can see the home page but have no further access. (I show a “check your email to verify your account” message on the home page if they aren’t confirmed yet).
  2. User doesn’t see email. Clicks “send it again” and we do. User is stuck here until they actually get the email and verify.
  3. If the user token expires, etc., then when they return they won’t be authenticated. They’ll have to go back to the login page, and only option at this point is either a) do a password reset or b) use a magic link (which I also support).

So, bottom line… if they wait a long time and their token expires, there’s no way to get a new validation link other than password reset or magic link. Which I think is fine for me.

Alternatively, I could add an option to enter an email and get a new validation link but I don’t see the need for it.