ash_authentication/documentation/dsls/DSL:-AshAuthentication.AddOn.Confirmation.md
dependabot[bot] 99c20cce76
chore(deps): Bump ash from 2.17.10 to 2.17.12 (#524)
* chore(deps): Bump ash from 2.17.10 to 2.17.12

Bumps [ash](https://github.com/ash-project/ash) from 2.17.10 to 2.17.12.
- [Release notes](https://github.com/ash-project/ash/releases)
- [Changelog](https://github.com/ash-project/ash/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ash-project/ash/compare/v2.17.10...v2.17.12)

---
updated-dependencies:
- dependency-name: ash
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* docs: Update Spark DSL docs.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: James Harton <james@harton.nz>
2023-12-15 09:07:32 +13:00

8.9 KiB

DSL: AshAuthentication.AddOn.Confirmation

Confirmation support.

Sometimes when creating a new user, or changing a sensitive attribute (such as their email address) you may want to wait for the user to confirm by way of sending them a confirmation token to prove that it was really them that took the action.

In order to add confirmation to your resource, it must been the following minimum requirements:

  1. Have a primary key
  2. Have at least one attribute you wish to confirm
  3. Tokens must be enabled

Example

defmodule MyApp.Accounts.User do
  use Ash.Resource,
    extensions: [AshAuthentication]

  attributes do
    uuid_primary_key :id
    attribute :email, :ci_string, allow_nil?: false
  end

  authentication do
    api MyApp.Accounts

    add_ons do
      confirmation :confirm do
        monitor_fields [:email]
        sender MyApp.ConfirmationSender
      end
    end

    strategies do
      # ...
    end
  end

  identities do
    identity :email, [:email] do
      eager_check_with MyApp.Accounts
    end
  end
end

Attributes

A confirmed_at attribute will be added to your resource if it's not already present (see confirmed_at_field in the DSL documentation).

Actions

By default confirmation will add an action which updates the confirmed_at attribute as well as retrieving previously stored changes and applying them to the resource.

If you wish to perform the confirm action directly from your code you can do so via the AshAuthentication.Strategy protocol.

Example

iex> strategy = Info.strategy!(Example.User, :confirm)
...> {:ok, user} = Strategy.action(strategy, :confirm, %{"confirm" => confirmation_token()})
...> user.confirmed_at >= one_second_ago()
true

Plugs

Confirmation provides a single endpoint for the :confirm phase. If you wish to interact with the plugs directly, you can do so via the AshAuthentication.Strategy protocol.

Example

iex> strategy = Info.strategy!(Example.User, :confirm)
...> conn = conn(:get, "/user/confirm", %{"confirm" => confirmation_token()})
...> conn = Strategy.plug(strategy, :confirm, conn)
...> {_conn, {:ok, user}} = Plug.Helpers.get_authentication_result(conn)
...> user.confirmed_at >= one_second_ago()
true

DSL Documentation

User confirmation flow

  • :name (t:atom/0) - Required. Uniquely identifies the add-on.

  • :token_lifetime - How long should the confirmation token be valid. If no unit is provided, then hours is assumed.
    Defaults to 3 days. The default value is {3, :days}.

  • :monitor_fields (list of t:atom/0) - Required. A list of fields to monitor for changes (eg [:email, :phone_number]). The confirmation will only be sent when one of these fields are changed.

  • :confirmed_at_field (t:atom/0) - The name of a field to store the time that the last confirmation took place. This attribute will be dynamically added to the resource if not already present. The default value is :confirmed_at.

  • :confirm_on_create? (t:boolean/0) - Generate and send a confirmation token when a new resource is created? Will only trigger when a create action is executed and one of the monitored fields is being set. The default value is true.

  • :confirm_on_update? (t:boolean/0) - Generate and send a confirmation token when a resource is changed? Will only trigger when an update action is executed and one of the monitored fields is being set. The default value is true.

  • :inhibit_updates? (t:boolean/0) - Wait until confirmation is received before actually changing a monitored field? If a change to a monitored field is detected, then the change is stored in the token resource and the changeset updated to not make the requested change. When the token is confirmed, the change will be applied. This could be potentially weird for your users, but useful in the case of a user changing their email address or phone number where you want to verify that the new contact details are reachable. The default value is true.

  • :sender - Required. How to send the confirmation instructions to the user. Allows you to glue sending of confirmation instructions to swoosh, ex_twilio or whatever notification system is appropriate for your application. Accepts a module, module and opts, or a function that takes a record, reset token and options. The options will be a keyword list containing the original changeset, before any changes were inhibited. This allows you to send an email to the user's new email address if it is being changed for example. See AshAuthentication.Sender for more information.

  • :confirm_action_name (t:atom/0) - The name of the action to use when performing confirmation. If this action is not already present on the resource, it will be created for you. The default value is :confirm.

authentication.add_ons.confirmation

confirmation name \\ :confirm

User confirmation flow

Arguments

Name Type Default Docs
name{: #authentication-add_ons-confirmation-name .spark-required} atom Uniquely identifies the add-on.

Options

Name Type Default Docs
monitor_fields{: #authentication-add_ons-confirmation-monitor_fields .spark-required} list(atom) A list of fields to monitor for changes (eg [:email, :phone_number]). The confirmation will only be sent when one of these fields are changed.
sender{: #authentication-add_ons-confirmation-sender .spark-required} (any, any, any -> any) | module How to send the confirmation instructions to the user. Allows you to glue sending of confirmation instructions to swoosh, ex_twilio or whatever notification system is appropriate for your application. Accepts a module, module and opts, or a function that takes a record, reset token and options. The options will be a keyword list containing the original changeset, before any changes were inhibited. This allows you to send an email to the user's new email address if it is being changed for example. See AshAuthentication.Sender for more information.
token_lifetime{: #authentication-add_ons-confirmation-token_lifetime } pos_integer | {pos_integer, :days | :hours | :minutes | :seconds} {3, :days} How long should the confirmation token be valid. If no unit is provided, then hours is assumed. Defaults to 3 days.
confirmed_at_field{: #authentication-add_ons-confirmation-confirmed_at_field } atom :confirmed_at The name of a field to store the time that the last confirmation took place. This attribute will be dynamically added to the resource if not already present.
confirm_on_create?{: #authentication-add_ons-confirmation-confirm_on_create? } boolean true Generate and send a confirmation token when a new resource is created? Will only trigger when a create action is executed and one of the monitored fields is being set.
confirm_on_update?{: #authentication-add_ons-confirmation-confirm_on_update? } boolean true Generate and send a confirmation token when a resource is changed? Will only trigger when an update action is executed and one of the monitored fields is being set.
inhibit_updates?{: #authentication-add_ons-confirmation-inhibit_updates? } boolean true Wait until confirmation is received before actually changing a monitored field? If a change to a monitored field is detected, then the change is stored in the token resource and the changeset updated to not make the requested change. When the token is confirmed, the change will be applied. This could be potentially weird for your users, but useful in the case of a user changing their email address or phone number where you want to verify that the new contact details are reachable.
confirm_action_name{: #authentication-add_ons-confirmation-confirm_action_name } atom :confirm The name of the action to use when performing confirmation. If this action is not already present on the resource, it will be created for you.

Introspection

Target: AshAuthentication.AddOn.Confirmation