Packages
pow
1.0.3
1.0.39
1.0.38
1.0.37
1.0.36
1.0.35
1.0.34
1.0.33
1.0.32
1.0.31
1.0.30
1.0.29
1.0.28
1.0.27
1.0.26
1.0.25
1.0.24
1.0.23
1.0.22
1.0.21
1.0.20
1.0.19
1.0.18
1.0.17
1.0.16
1.0.15
1.0.14
1.0.13
1.0.12
1.0.11
1.0.10
1.0.9
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc.4
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.1.0-rc.1
0.1.0-alpha.8
0.1.0-alpha.7
retired
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
0.1.0-alpha
Robust user authentication solution
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/extensions/email_confirmation/ecto/schema.ex
defmodule PowEmailConfirmation.Ecto.Schema do
@moduledoc false
use Pow.Extension.Ecto.Schema.Base
alias Ecto.Changeset
alias Pow.{Extension.Ecto.Schema, UUID}
@impl true
def validate!(_config, module) do
Schema.require_schema_field!(module, :email, PowEmailConfirmation)
end
@impl true
def attrs(_config) do
[
{:email_confirmation_token, :string},
{:email_confirmed_at, :utc_datetime},
{:unconfirmed_email, :string}
]
end
@impl true
def indexes(_config) do
[{:email_confirmation_token, true}]
end
@impl true
def changeset(%{errors: []} = changeset, _attrs, _config) do
current_email = changeset.data.email
new_email = Changeset.get_field(changeset, :email)
state = Ecto.get_meta(changeset.data, :state)
changeset
|> maybe_put_email_confirmation_token(state, current_email, new_email)
|> maybe_set_unconfirmed_email(state, current_email, new_email)
end
def changeset(changeset, _attrs, _config), do: changeset
@spec confirm_email_changeset(Ecto.Schema.t() | Changeset.t()) :: Changeset.t()
def confirm_email_changeset(%Changeset{data: %{unconfirmed_email: unconfirmed_email}} = changeset) when not is_nil(unconfirmed_email) do
confirm_email(changeset, unconfirmed_email)
end
def confirm_email_changeset(%Changeset{data: %{email_confirmed_at: confirmed_at, email: email}} = changeset) when is_nil(confirmed_at) do
confirm_email(changeset, email)
end
def confirm_email_changeset(%Changeset{} = changeset), do: changeset
def confirm_email_changeset(user) do
user
|> Changeset.change()
|> confirm_email_changeset()
end
defp confirm_email(changeset, email) do
confirmed_at = Pow.Ecto.Schema.__timestamp_for__(changeset.data.__struct__, :email_confirmed_at)
changes = [email_confirmed_at: confirmed_at, email: email, unconfirmed_email: nil]
changeset
|> Changeset.change(changes)
|> Changeset.unique_constraint(:email)
end
defp maybe_put_email_confirmation_token(changeset, state, current_email, new_email) when current_email != new_email or state == :built do
changeset
|> Changeset.put_change(:email_confirmation_token, UUID.generate())
|> Changeset.unique_constraint(:email_confirmation_token)
end
defp maybe_put_email_confirmation_token(changeset, _state, _current_email, _new_email), do: changeset
defp maybe_set_unconfirmed_email(changeset, :loaded, current_email, new_email) when current_email != new_email do
changeset
|> Changeset.put_change(:email, current_email)
|> Changeset.put_change(:unconfirmed_email, new_email)
end
defp maybe_set_unconfirmed_email(changeset, _state, _current_email, _new_email), do: changeset
end