Packages
charon
0.0.3-alpha
4.3.0
4.3.0-beta1
4.2.0
4.2.0-beta3
4.2.0-beta2
4.2.0-beta1
4.1.0
4.0.1
4.0.0
4.0.0-beta3
4.0.0-beta2
4.0.0-beta1
3.4.1
3.4.0
3.3.0
3.2.0
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
3.0.0-beta1
2.8.0
2.8.0-beta1
2.7.3
2.7.2
2.7.1
2.7.0
2.6.1
2.6.0
2.5.0
2.4.0
2.3.0
2.2.0
2.2.0-beta
2.1.3
2.1.2
2.1.2-beta
2.1.1
2.1.0
2.0.0
1.3.4
1.3.3
1.3.2-beta
1.3.1-beta
1.3.0-beta
1.2.0-beta
1.1.0-beta
1.0.1-beta
1.0.0-beta1
0.0.4-alpha
0.0.3-alpha
0.0.2-alpha
0.0.1-alpha
Authentication & sessions for API's.
Current section
Files
Jump to
Current section
Files
lib/charon/auth_challenge/pre_sent_challenge.ex
defmodule Charon.AuthChallenge.PreSentChallenge do
@moduledoc """
TOTP-challenge for which the answer has been sent to the user by SMS/email.
Basically the same as `Charon.AuthChallenge.TotpChallenge` but with a longer default period (5 minutes).
## Config
Additional config is required for this module under `optional.charon_pre_sent_challenge`:
Charon.Config.from_enum(
...,
optional_modules: %{
charon_pre_sent_challenge: %{
...
}
}
)
The following configuration options are supported:
- `:send_challenge_callback` (required). A function/2 used to send a TOTP code to the user. The user and the code are passed in. Must return `:ok` or `{:error, message}`.
- `:period` (optional, default 300). The duration in seconds in which a single OTP code is valid.
"""
@challenge_name "pre_sent"
use Charon.AuthChallenge
alias Charon.AuthChallenge.TotpChallenge
alias Charon.Internal
@optional_config_field :charon_pre_sent_challenge
@defaults %{period: 5 * 60}
@required [:send_challenge_callback]
@impl true
def challenge_init(conn, params, user, config) do
with {:ok, conn, _} <- super(conn, params, user, config),
%{send_challenge_callback: callback} = process_config(config),
code = TotpChallenge.generate_code(user, override_config(config)),
:ok <- callback.(user, code) do
{:ok, conn, nil}
end
end
@impl true
def challenge_complete(conn, params, user, config) do
with :ok <- AuthChallenge.verify_enabled(user, @challenge_name, config) do
config = override_config(config)
TotpChallenge.challenge_complete(conn, params, user, config)
end
end
@impl true
def setup_complete(conn, params, user, config) do
with {:ok, conn, _} <- super(conn, params, user, config),
enabled = AuthChallenge.put_enabled(user, @challenge_name, config),
params = %{config.enabled_auth_challenges_field => enabled},
{:ok, _user} <- AuthChallenge.update_user(user, params, config) do
{:ok, conn, nil}
end
end
@doc false
def generate_code(user, config) do
config = override_config(config)
TotpChallenge.generate_code(user, config)
end
###########
# Private #
###########
defp process_config(config) do
Internal.process_optional_config(config, @optional_config_field, @defaults, @required)
end
defp override_config(config = %{optional_modules: optional}) do
mod_config = config |> process_config() |> Map.merge(%{totp_label: "", totp_issuer: ""})
%{config | optional_modules: Map.put(optional, :charon_totp_challenge, mod_config)}
end
end