Closed vadimshvetsov closed 4 years ago
You have to block authentication after sign up if the e-mail is unconfirmed, so you need to set it up like this:
def sign_up(_, %{input: input}, _) do
case {:ok, user, conn} <- Pow.Plug.create_user(conn(), input) do
{:ok, _user, conn} -> maybe_require_confirmation(conn)
{:error, changeset, conn} -> {:error, changeset}
end
end
defp maybe_require_confirmation(conn) do
case PowEmailConfirmation.Plug.email_unconfirmed?(conn) do
true ->
{:ok,
%{
session: %{
access_token: conn.private[:api_access_token],
renewal_token: conn.private[:api_renewal_token]
},
user: Pow.Plug.current_user(conn)
}}
false ->
{:error, changeset, _conn} ->
{:error, changeset}
false ->
send_email_confirmation_email(conn)
Pow.Plug.delete(conn)
{:error, "requires email confirmation"}
end
end
Though if you already know that all users will need email confirmation then you can just bypass the pow auth logic entirely and just create the user directly instead of using Pow.Plug.create_user/2
:
def sign_up(_, %{input: input}, _) do
with {:ok, user} <- Pow.Ecto.Context.create(input, otp_app: proling_web) do
send_email_confirmation_email(conn)
{:ok, %{user: user}}
else
{:error, changeset, _conn} -> {:error, changeset}
end
end
end
@danschultzer Thanks a lot for this great explanation. I definitely agreed but the drawback of requiring email confirmation for login like double current password and secure password rules originates a bad UX. Not all systems need to be super secure for UX sake I mean. So I still can't find a way to just change URL for emails if I have external frontend, is it possible with little changes without reimplementing sending email on my own?
I think there is no better way right now to change only change url without building email from scratch so it might be closed right now.
Sorry @vadimshvetsov, got away from this issue.
I definitely agreed but the drawback of requiring email confirmation for login like double current password and secure password rules originates a bad UX. Not all systems need to be super secure for UX sake I mean.
Oh I understand what you were asking for now. Your setup is fine then 😄
So I still can't find a way to just change URL for emails if I have external frontend, is it possible with little changes without reimplementing sending email on my own?
So first, you can change the domain by using the Phoenix URL generator options:
config :my_app, MyAppWeb.Endpoint,
# ..,
url: [scheme: "https", host: "example.com", port: 443]
Pow uses the router helpers so with that set up you can instead call e.g. Routes.pow_email_confirmation_confirmation_url(conn, :show, token)
rather than building it manually.
You would still need to generate and send the e-mail, as the mail delivery are private methods inside the Pow controllers (except for PowEmailConfirmation.Phoenix.ControllerCallbacks.send_confirmation_email/2
). I'm planning to refactor some of the mailer logic with https://github.com/danschultzer/pow/issues/469, so might find a way to make this easier.
@danschultzer Thanks again, Dan! It looks like changing Phoenix.Endpoint will change Phoenix url instead pointing my React Frontend app
It looks like changing Phoenix.Endpoint will change Phoenix url instead pointing my React Frontend app
Oh right, I incorrectly assumed you just wanted to replicate the URL with the front-end domain. In that case your setup is probably the best that can be done currently. If you find any opportunities for refactoring Pow to make this easier, please let me know! I'm not sure the refactoring of the e-mail logic I'm planning would help much here.
I would like to move away from requiring conn
for the mailer if possible, so maybe it would be good to do both that and a slight change to the logic so you only have to call one method to generate and deliver the email?
@danschultzer I love what Pow offers for Phoenix users but it's not easy to use in GraphQL API which doesn't rely on request as well as using Phoenix. I would happy to help. By the way, when Phoenix will do their auth based on conn Pow might offer auth without conn and it could be killer feature for Absinthe users
By the way, when Phoenix will do their auth based on conn Pow might offer auth without conn and it could be killer feature for Absinthe users
Agreed! I'm planning to let Pow v1.1.0 be the final version of Pow, with hard deprecations for everything I've learned to make all of this much simpler. I've realized that I'm depending too much on conn
and probably should do a lot more with just using the Endpoint
module (as Phoenix does).
Is there any way to change confirmation or reset password URL in emails without reimplementing it like this in GraphQL resolvers?
With this code I've got a correct link but user gets authenticated while still has unconfirmed email. UPD: I've got that returning
uncofirmedEmail => nil
with create is totally ok.And my schema