stocks29

stocks29

Is it possible to manually re-send the confirmation email?

I’m curious if this can be done through code.

Also curious if there is a way to enable this in ash_authentication_phoenix so the user can re-send the email themself (without having to build out custom UI for this).

Showing Posts 1 to 6

zachdaniel

zachdaniel

Creator of Ash

There definitely isn’t a built in UI for this, so something custom would need to be added on your end. With that said, are you storing all tokens using the store_all_tokens? config? If so you can lookup the old token and send it, something like:

Token
|> Ash.Query.filter(subject == ^"user_#{^user.id}" and purpose == "confirm" and expires_at < now())
|> Ash.read_one()
|> case do
  ... # call your sender with the user and the token
end

If you aren’t storing tokens, then you’d do something like

claims = %{"act" => "confirm"}
strategy = AshAuthentication.Info.strategy(User, :confirmation)

{:ok, token, _claims} = Jwt.token_for_user(user, claims, token_lifetime: strategy.token_lifetime)

# call your sender with the user and the token

This definitely isn’t as ergonomic as it could be, but adding resend with a nice interface (likely via an update action on the user, like resend_confirmation, would likely take some time, so I’m looking to provide ways you can achieve this in the short term. If you could open an issue requesting first-class support for this that would be great :slight_smile:

stocks29

stocks29 OP

Thanks for the quick response @zachdaniel, I’ll give this a try.

sodapopcan

sodapopcan

I’m finally digging into Ash and +1’ing this as a not-yet-but-probably-will-be user :upside_down_face:

stocks29

stocks29 OP

I dug into this a bit this morning. I am storing the tokens. I think this will work as long as the token hasn’t yet expired. If the token has expired, I think I would still need a way to programmatically generate a new token. Is there a way to do this?

I suppose I could also extend the expiration on the token but that doesn’t seem ideal from a security perspective.

zachdaniel

zachdaniel

Creator of Ash

Generating a new token is definitely doable :slight_smile: There re actions on the token resource to generate new ones, so you can create a new confirm token at any point.

To see the actions available on the token resource:

Ash.Resource.Info.actions(YourApp.Accounts.Tokens)
zac

zac

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.

— All posts loaded —

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
rahultumpala
Hello, I have an Elixir backend that implements a custom protocol over TCP. I want to load test the backend and assess the performance o...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews