Packages
pow
1.0.17
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/invitation/ecto/schema.ex
defmodule PowInvitation.Ecto.Schema do
@moduledoc """
Handles the invitation schema for user.
## Customize PowInvitation associations or fields
If you need to modify any of the associations or fields that `PowInvitation`
adds to the user schema, you can override them by defining them before
`pow_user_fields/0`:
defmodule MyApp.Users.User do
use Ecto.Schema
use Pow.Ecto.Schema
use Pow.Extension.Ecto.Schema,
extensions: [PowInvitation]
schema "users" do
belongs_to :invited_by, __MODULE__
has_many :invited_users __MODULE__, foreign_key: :invited_by_id, on_delete: delete_all
field :invitation_token, :string
field :invitation_accepted_at, :utc_datetime
pow_user_fields()
timestamps()
end
end
"""
use Pow.Extension.Ecto.Schema.Base
alias Ecto.Changeset
alias Pow.UUID
@doc false
@impl true
def attrs(_config) do
[
{:invitation_token, :string},
{:invitation_accepted_at, :utc_datetime}
]
end
@doc false
@impl true
def assocs(_config) do
[
{:belongs_to, :invited_by, :users},
{:has_many, :invited_users, :users, foreign_key: :invited_by_id}
]
end
@doc false
@impl true
def indexes(_config) do
[{:invitation_token, true}]
end
@doc false
@impl true
defmacro __using__(_config) do
quote do
def invite_changeset(changeset, invited_by, attrs), do: pow_invite_changeset(changeset, invited_by, attrs)
defdelegate pow_invite_changeset(changeset, invited_by, attrs), to: unquote(__MODULE__), as: :invite_changeset
defoverridable invite_changeset: 3
end
end
@doc """
Invites user.
It's important to note that this changeset should not include the changeset
method in the user schema module if `PowEmailConfirmation` has been enabled.
This is because the e-mail is assumed confirmed already if the user can
accept the invitation.
A unique `:invitation_token` will be generated, and `invited_by` association
will be set. Only the user id will be set, and the persisted user won't have
any password for authentication.
"""
@spec invite_changeset(Ecto.Schema.t() | Changeset.t(), Ecto.Schema.t(), map()) :: Changeset.t()
def invite_changeset(%Changeset{data: user} = changeset, invited_by, attrs) do
changeset
|> user.__struct__.pow_user_id_field_changeset(attrs)
|> invitation_token_changeset()
|> invited_by_changeset(invited_by)
end
def invite_changeset(user, invited_by, attrs) do
user
|> Changeset.change()
|> invite_changeset(invited_by, attrs)
end
defp invitation_token_changeset(changeset) do
changeset
|> Changeset.put_change(:invitation_token, UUID.generate())
|> Changeset.unique_constraint(:invitation_token)
end
defp invited_by_changeset(%Changeset{data: data} = changeset, invited_by) do
data = Ecto.build_assoc(invited_by, :invited_users, data)
Changeset.assoc_constraint(%{changeset | data: data}, :invited_by)
end
@doc """
Accepts an invitation.
The changeset method in user schema module is called, and
`:invitation_accepted_at` will be updated. The password can be set, and the
user id updated.
"""
@spec accept_invitation_changeset(Ecto.Schema.t() | Changeset.t(), map()) :: Changeset.t()
def accept_invitation_changeset(%Changeset{data: %user_mod{}} = changeset, attrs) do
accepted_at = Pow.Ecto.Schema.__timestamp_for__(user_mod, :invitation_accepted_at)
changeset
|> user_mod.changeset(attrs)
|> Changeset.change(invitation_accepted_at: accepted_at)
end
def accept_invitation_changeset(user, attrs) do
user
|> Changeset.change()
|> accept_invitation_changeset(attrs)
end
end