Packages
ash_authentication
5.0.0-rc.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/add_ons/confirmation/confirm_change.ex
# SPDX-FileCopyrightText: 2022 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defmodule AshAuthentication.AddOn.Confirmation.ConfirmChange do
@moduledoc """
Performs a change based on the contents of a confirmation token.
"""
use Ash.Resource.Change
alias AshAuthentication.{AddOn.Confirmation.Actions, Info, Jwt}
alias Ash.{
Changeset,
Error.Changes.InvalidArgument,
Error.Framework.AssumptionFailed,
Resource.Change
}
@doc false
@impl true
@spec change(Changeset.t(), keyword, Change.context()) :: Changeset.t()
def change(changeset, _opts, context) do
case Info.strategy_for_action(changeset.resource, changeset.action.name) do
{:ok, strategy} ->
do_change(changeset, strategy, context)
:error ->
raise AssumptionFailed,
message: "Action does not correlate with an authentication strategy"
end
end
defp do_change(changeset, strategy, context) do
changeset
|> Changeset.set_context(%{
private: %{
ash_authentication?: true
}
})
|> Changeset.before_action(&apply_confirmation_token(&1, strategy, context))
end
defp apply_confirmation_token(changeset, strategy, context) do
with token when is_binary(token) <-
Changeset.get_argument(changeset, :confirm),
{:ok, %{"act" => action, "jti" => jti}, _} <-
Jwt.verify(token, changeset.resource, Ash.Context.to_opts(context)),
true <-
to_string(strategy.confirm_action_name) == action,
{:ok, changes} <- Actions.get_changes(strategy, jti, Ash.Context.to_opts(context)) do
allowed_changes =
if strategy.inhibit_updates?,
do: Map.take(changes, Enum.map(strategy.monitor_fields, &to_string/1)),
else: %{}
changeset
|> Changeset.force_change_attributes(allowed_changes)
|> Changeset.force_change_attribute(strategy.confirmed_at_field, DateTime.utc_now())
else
_ ->
Changeset.add_error(
changeset,
InvalidArgument.exception(field: :confirm, message: "is not valid")
)
end
end
end