ash_authentication/documentation/dsls/DSL:-AshAuthentication.Strategy.MagicLink.cheatmd
2023-09-26 23:42:46 -04:00

337 lines
8.6 KiB
Text

<!--
This file was generated by Spark. Do not edit it by hand.
-->
# DSL: AshAuthentication.Strategy.MagicLink
Strategy for authentication using a magic link.
In order to use magic link authentication your resource needs to meet the
following minimum requirements:
1. Have a primary key.
2. A uniquely constrained identity field (eg `username` or `email`)
3. Have tokens enabled.
There are other options documented in the DSL.
### Example
```elixir
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
strategies do
magic_link do
identity_field :email
sender fn user, token, _opts ->
MyApp.Emails.deliver_magic_link(user, token)
end
end
end
end
identities do
identity :unique_email, [:email]
end
end
```
## Actions
By default the magic link strategy will automatically generate the request and
sign-in actions for you, however you're free to define them yourself. If you
do, then the action will be validated to ensure that all the needed
configuration is present.
If you wish to work with the actions directly from your code you can do so via
the `AshAuthentication.Strategy` protocol.
### Examples
Requesting that a magic link token is sent for a user:
iex> strategy = Info.strategy!(Example.User, :magic_link)
...> user = build_user()
...> Strategy.action(strategy, :request, %{"username" => user.username})
:ok
Signing in using a magic link token:
...> {:ok, token} = MagicLink.request_token_for(strategy, user)
...> {:ok, signed_in_user} = Strategy.action(strategy, :sign_in, %{"token" => token})
...> signed_in_user.id == user
true
## Plugs
The magic link strategy provides plug endpoints for both request and sign-in
actions.
If you wish to work with the plugs directly, you can do so via the
`AshAuthentication.Strategy` protocol.
### Examples:
Dispatching to plugs directly:
iex> strategy = Info.strategy!(Example.User, :magic_link)
...> user = build_user()
...> conn = conn(:post, "/user/magic_link/request", %{"user" => %{"username" => user.username}})
...> conn = Strategy.plug(strategy, :request, conn)
...> {_conn, {:ok, nil}} = Plug.Helpers.get_authentication_result(conn)
...> {:ok, token} = MagicLink.request_token_for(strategy, user)
...> conn = conn(:get, "/user/magic_link", %{"token" => token})
...> conn = Strategy.plug(strategy, :sign_in, conn)
...> {_conn, {:ok, signed_in_user}} = Plug.Helpers.get_authentication_result(conn)
...> signed_in_user.id == user.id
true
## DSL Documentation
Strategy for authenticating using local users with a magic link
* `:identity_field` (`t:atom/0`) - The name of the attribute which uniquely identifies the user.
Usually something like `username` or `email_address`. The default value is `:username`.
* `:token_lifetime` - How long the sign in token is valid.
If no unit is provided, then `minutes` is assumed. The default value is `{10, :minutes}`.
* `:request_action_name` (`t:atom/0`) - The name to use for the request action.
If not present it will be generated by prepending the strategy name
with `request_`.
* `:single_use_token?` (`t:boolean/0`) - Automatically revoke the token once it's been used for sign in. The default value is `true`.
* `:sign_in_action_name` (`t:atom/0`) - The name to use for the sign in action.
If not present it will be generated by prepending the strategy name
with `sign_in_with_`.
* `:token_param_name` (`t:atom/0`) - The name of the token parameter in the incoming sign-in request. The default value is `:token`.
* `:sender` - Required. How to send the magic link to the user.
Allows you to glue sending of magic links to [swoosh](https://hex.pm/packages/swoosh), [ex_twilio](https://hex.pm/packages/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.
See `AshAuthentication.Sender` for more information.
## authentication.strategies.magic_link
```elixir
magic_link name \ :magic_link
```
Strategy for authenticating using local users with a magic link
### Options
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th colspan=2>Docs</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">
<a id="name-sender" href="#name-sender">
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
sender
</span>
</a>
<sup style="color: red">*</sup>
</td>
<td style="text-align: left">
<code class="inline">(any, any, any -> any) | module</code>
</td>
<td style="text-align: left">
</td>
<td style="text-align: left" colspan=2>
How to send the magic link to the user.
Allows you to glue sending of magic links to [swoosh](https://hex.pm/packages/swoosh), [ex_twilio](https://hex.pm/packages/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.
See `AshAuthentication.Sender` for more information.
</td>
</tr>
<tr>
<td style="text-align: left">
<a id="name-identity_field" href="#name-identity_field">
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
identity_field
</span>
</a>
</td>
<td style="text-align: left">
<code class="inline">atom</code>
</td>
<td style="text-align: left">
<code class="inline">:username</code>
</td>
<td style="text-align: left" colspan=2>
The name of the attribute which uniquely identifies the user.
Usually something like `username` or `email_address`.
</td>
</tr>
<tr>
<td style="text-align: left">
<a id="name-token_lifetime" href="#name-token_lifetime">
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
token_lifetime
</span>
</a>
</td>
<td style="text-align: left">
<code class="inline">pos_integer | {pos_integer, :days | :hours | :minutes | :seconds}</code>
</td>
<td style="text-align: left">
<code class="inline">{10, :minutes}</code>
</td>
<td style="text-align: left" colspan=2>
How long the sign in token is valid.
If no unit is provided, then `minutes` is assumed.
</td>
</tr>
<tr>
<td style="text-align: left">
<a id="name-request_action_name" href="#name-request_action_name">
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
request_action_name
</span>
</a>
</td>
<td style="text-align: left">
<code class="inline">atom</code>
</td>
<td style="text-align: left">
</td>
<td style="text-align: left" colspan=2>
The name to use for the request action.
If not present it will be generated by prepending the strategy name
with `request_`.
</td>
</tr>
<tr>
<td style="text-align: left">
<a id="name-single_use_token?" href="#name-single_use_token?">
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
single_use_token?
</span>
</a>
</td>
<td style="text-align: left">
<code class="inline">boolean</code>
</td>
<td style="text-align: left">
<code class="inline">true</code>
</td>
<td style="text-align: left" colspan=2>
Automatically revoke the token once it's been used for sign in.
</td>
</tr>
<tr>
<td style="text-align: left">
<a id="name-sign_in_action_name" href="#name-sign_in_action_name">
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
sign_in_action_name
</span>
</a>
</td>
<td style="text-align: left">
<code class="inline">atom</code>
</td>
<td style="text-align: left">
</td>
<td style="text-align: left" colspan=2>
The name to use for the sign in action.
If not present it will be generated by prepending the strategy name
with `sign_in_with_`.
</td>
</tr>
<tr>
<td style="text-align: left">
<a id="name-token_param_name" href="#name-token_param_name">
<span style="font-family: Inconsolata, Menlo, Courier, monospace;">
token_param_name
</span>
</a>
</td>
<td style="text-align: left">
<code class="inline">atom</code>
</td>
<td style="text-align: left">
<code class="inline">:token</code>
</td>
<td style="text-align: left" colspan=2>
The name of the token parameter in the incoming sign-in request.
</td>
</tr>
</tbody>
</table>
### Introspection
Target: `AshAuthentication.Strategy.MagicLink`