Packages
ash_authentication
4.7.2
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_preparation.ex
defmodule AshAuthentication.Strategy.MagicLink.SignInPreparation do
@moduledoc """
Prepare a query for sign in.
"""
use Ash.Resource.Preparation
alias AshAuthentication.{Info, Jwt, TokenResource}
alias Ash.{Query, Resource, Resource.Preparation}
require Ash.Query
import Ash.Expr
@doc false
@impl true
@spec prepare(Query.t(), keyword, Preparation.Context.t()) :: Query.t()
def prepare(query, _opts, context) do
subject_name =
query.resource
|> Info.authentication_subject_name!()
|> to_string()
with {:ok, strategy} <- Info.strategy_for_action(query.resource, query.action.name),
token when is_binary(token) <- Query.get_argument(query, strategy.token_param_name),
{:ok, %{"act" => token_action, "sub" => subject} = claims, _} <-
Jwt.verify(token, query.resource, Ash.Context.to_opts(context)),
^token_action <- to_string(strategy.sign_in_action_name),
%URI{path: ^subject_name, query: primary_key} <- URI.parse(subject) do
query
|> Query.set_context(%{private: %{ash_authentication?: true}})
|> then(fn query ->
cond do
not is_nil(primary_key) ->
primary_key =
primary_key
|> URI.decode_query()
|> Enum.to_list()
Query.filter(query, ^primary_key)
identity = claims["identity"] ->
identity_field = strategy.identity_field
Query.filter(query, ^ref(identity_field) == ^identity)
true ->
Query.do_filter(query, false)
end
end)
|> Query.after_action(fn
query, [record] ->
if strategy.single_use_token? do
token_resource = Info.authentication_tokens_token_resource!(query.resource)
:ok = TokenResource.revoke(token_resource, token, Ash.Context.to_opts(context))
end
{:ok, token, _claims} = Jwt.token_for_user(record, %{}, Ash.Context.to_opts(context))
{:ok, [Resource.put_metadata(record, :token, token)]}
_query, [] ->
{:ok, []}
end)
else
_ -> Query.do_filter(query, false)
end
end
end