Packages
ash_authentication
4.7.3
5.0.0-rc.12
5.0.0-rc.11
5.0.0-rc.10
5.0.0-rc.9
5.0.0-rc.8
5.0.0-rc.7
5.0.0-rc.6
5.0.0-rc.5
5.0.0-rc.4
5.0.0-rc.3
5.0.0-rc.2
5.0.0-rc.1
5.0.0-rc.0
4.14.1
4.14.0
4.13.7
4.13.6
4.13.5
4.13.4
4.13.3
4.13.2
retired
4.13.1
retired
4.13.0
4.12.0
4.11.0
4.10.0
4.9.9
4.9.8
4.9.7
4.9.6
4.9.5
4.9.4
4.9.3
4.9.2
4.9.1
4.9.0
4.8.7
4.8.6
4.8.5
4.8.3
4.8.2
4.8.1
4.8.0
4.7.6
4.7.5
4.7.4
4.7.3
4.7.2
4.7.1
4.7.0
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.6
4.5.5
4.5.4
4.5.3
4.5.2
4.5.1
4.5.0
4.4.9
4.4.8
4.4.7
4.4.6
4.4.5
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.12
4.3.11
4.3.10
4.3.9
4.3.8
4.3.7
4.3.6
4.3.5
4.3.4
4.3.3
4.3.2
4.3.1
4.3.0
4.2.7
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.4
4.0.3
4.0.2
4.0.1
4.0.0
4.0.0-rc.6
4.0.0-rc.5
4.0.0-rc.3
4.0.0-rc.2
4.0.0-rc.1
4.0.0-rc.0
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.16
3.11.15
3.11.14
3.11.13
3.11.12
3.11.11
3.11.10
3.11.9
3.11.8
3.11.7
3.11.6
3.11.5
3.11.4
3.11.3
3.11.2
3.11.1
3.11.0
3.10.8
3.10.7
3.10.6
3.10.5
3.10.4
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.0
3.7.9
3.7.8
3.7.6
3.7.5
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.1
3.6.0
3.5.3
3.5.2
3.5.1
3.5.0
3.3.1
3.3.0
3.2.2
3.2.1
3.2.0
3.1.0
3.0.3
Authentication extension for the Ash Framework.
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/ash_authentication/strategies/magic_link/sign_in_change.ex
defmodule AshAuthentication.Strategy.MagicLink.SignInChange do
@moduledoc """
Set up a create action for magic link sign in.
"""
use Ash.Resource.Change
alias AshAuthentication.{Errors.InvalidToken, Info, Jwt, TokenResource}
alias Ash.{Changeset, Resource, Resource.Change}
@doc false
@impl true
@spec change(Changeset.t(), keyword, Change.Context.t()) :: Changeset.t()
def change(changeset, _otps, context) do
subject_name =
changeset.resource
|> Info.authentication_subject_name!()
|> to_string()
strategy = Info.strategy_for_action!(changeset.resource, changeset.action.name)
with token when is_binary(token) <-
Changeset.get_argument(changeset, strategy.token_param_name),
{:ok, %{"act" => token_action, "sub" => subject, "identity" => identity}, _} <-
Jwt.verify(token, changeset.resource, [], context),
^token_action <- to_string(strategy.sign_in_action_name),
%URI{path: ^subject_name} <- URI.parse(subject) do
changeset
|> Changeset.force_change_attribute(strategy.identity_field, identity)
|> Changeset.after_transaction(fn
_changeset, {:ok, record} ->
if strategy.single_use_token? do
token_resource = Info.authentication_tokens_token_resource!(changeset.resource)
:ok = TokenResource.revoke(token_resource, token)
end
{:ok, token, _claims} = Jwt.token_for_user(record, %{}, Ash.Context.to_opts(context))
{:ok, Resource.put_metadata(record, :token, token)}
_changeset, {:error, error} ->
{:error, error}
end)
else
_ ->
Ash.Changeset.add_error(
changeset,
InvalidToken.exception(
field: strategy.token_param_name,
type: :magic_link
)
)
end
end
end