polypush135

polypush135

Design choices around integrating phx_gen_auth with a mailer

What’s your thoughts on pros/cons of design choices as it relates to how you could follow up with using the phx_gen_auth and at what entry points you could integrating with say Swoosh or Bamboo?

Let’s take the user’s registration controller for example.

lib/my_app_web/controllers/user_registration_controller.ex

alias MyAppWeb.{Mailer, AccountEmail}

def create(conn, %{"user" => user_params}) do
    case Accounts.register_user(user_params) do
      {:ok, user} ->
        {:ok, _} =
          Accounts.deliver_user_confirmation_instructions(
            user,
            &Routes.user_confirmation_url(conn, :confirm, &1),
            &Mailer.deliver/1,
            &AccountEmail.confirmation_email/1
          )
      ...
    end
  end

You will notice that just as with the originally generated confirmation link helper, I’m also passing in the email and mailer’s deliver function to be used downstream.

Looking at how I choose to call said functions downstream in the context you will see

lib/my_app/accounts.ex

      UserNotifier.deliver_instructions(
        user,
        confirmation_url_fun.(encoded_token),
        deliver_fun,
        email_fun
      )

Using dependency injection I just pass the funs along to deliver_instructions

lib/my_app/accounts/user_notifier.ex
  def deliver_instructions(user, url, deliver_fun, email_fun) do
    Task.start(fn ->
      %{url: url, email: user.email}
      |> email_fun.()
      |> deliver_fun.()
    end)
  end

In this example, I’m using swoosh and a very basic async deliver call.

Where I’ve hit the wall is the expected result of deliver_instructions and trying to salvage many of the tests already generated by phx_gen_auth. The specific point of conflict looks to be the helper used for extracting the token.

  def extract_user_token(fun) do
    {:ok, captured} = fun.(&"[TOKEN]#{&1}[TOKEN]")
    [_, token, _] = String.split(captured.body, "[TOKEN]")
    token
  end

This got me to question: if the result of deliver_instructions is really only to benefit the test is it really the right choice? It’s likely it is, so with that what does deliver_instructions need to return to satisfy the test?

Most Liked

josevalim

josevalim

Creator of Elixir

Ah, the issue is that templates depend on Phoenix.View, which would require a dependency on Phoenix from our domain that we wanted to avoid.

But this will be addressed on Phoenix v1.6 because Phoenix.View is finally a separate package.

josevalim

josevalim

Creator of Elixir

I am on my phone but you can see how we did it on Bytepack: GitHub - dashbitco/bytepack_archive: Archive of bytepack.io · GitHub

We send emails from the account context and we pick the token up in our test support helpers.

LostKobrakai

LostKobrakai

Using dependency injection still requires the web layer to exist though. This makes sense for the example of urls, which to be useful also need to be served by the web layer.

The extraction of phoenix_view however allows both the web layer and the domain layer to depend on a library for handling templates on their own. No need for the web layer to exists for the domain to be able to send html emails – which is a sane requirements given even systems which do not serve an http endpoint might want to send html emails.

Where Next?

Popular in Discussions Top

Rustixir
Hi everyone, im working on find best language/framework/system for high concurrency, high performance and stable performance after wor...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39467 209
New
chuck
Let me start by stating an assumption: Phoenix is a great approach to building REST APIs. There are many reasons for this, but I will ass...
New
Ankhers
Just a little information upfront. Generally speaking, if I feel like I need to either break a pipe chain or use an anonymous function in...
New
AlexMcConnell
The reason that Rails is as popular as it is is because it’s very easy for relatively inexperienced developers to get a lot of work done....
588 19652 166
New
fireproofsocks
I’ve been working on an Elixir project that has required a lot of scripting. I usually reach for Elixir because I like it more (and in th...
New
restack_oslo
Hello, Please pardon me for any faux paux. I am 46 and this is my first time on a forum of any kind. I wanted to to get answers from tho...
New
AstonJ
If so I (and hopefully others!) might have some tips for you :slight_smile: But first, please say which area you’re finding most challen...
New
griffinbyatt
Sobelow Sobelow is a security-focused static analysis tool for the Phoenix framework. For security researchers, it is a useful tool for g...
New
kostonstyle
Hi all How can I compare haskell with elixir, included tools, webservices, ect. Thanks
New

Other popular topics Top

hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement