Packages

Integration with the Auth API from Supabase services. Provide authentication with MFA, password and magic link.

Current section

Files

Jump to
supabase_auth lib supabase auth schemas verify_otp.ex
Raw

lib/supabase/auth/schemas/verify_otp.ex

defmodule Supabase.Auth.Schemas.VerifyOTP do
@moduledoc false
use Ecto.Schema
import Ecto.Changeset
@type options :: %{redirect_to: String.t(), captcha_token: String.t()}
@type mobile :: %{phone: String.t(), token: String.t(), type: String.t(), options: options}
@type email :: %{email: String.t(), token: String.t(), type: String.t(), options: options}
@type token_hash :: %{token_hash: String.t(), type: String.t(), options: options}
@type t :: mobile | email | token_hash
def to_request(%{} = params) do
with {:ok, data} <- parse(params) do
captcha_token = get_in(data, [:options, :captcha_token])
{:ok, Map.put(data, :go_true_security, %{captcha_token: captcha_token})}
end
end
@mobile_otp_types ~w[sms phone_change]a
@email_otp_types ~w[signup invite magiclink recovery email_change email]a
@options_types %{redirect_to: :string, captcha_token: :string}
@mobile_types %{
phone: :string,
token: :string,
type: Ecto.ParameterizedType.init(Ecto.Enum, values: @mobile_otp_types),
options: :map
}
@email_types %{
email: :string,
token: :string,
type: Ecto.ParameterizedType.init(Ecto.Enum, values: @email_otp_types),
options: :map
}
@token_hash_types %{
token_hash: :string,
type: Ecto.ParameterizedType.init(Ecto.Enum, values: @email_otp_types),
options: :map
}
def parse(%{phone: _} = attrs) do
{%{}, @mobile_types}
|> cast(attrs, [:phone, :token, :type, :options])
|> validate_required([:phone, :token, :type])
|> options_changeset()
|> apply_action(:parse)
end
def parse(%{email: _} = attrs) do
{%{}, @email_types}
|> cast(attrs, [:email, :token, :type, :options])
|> validate_required([:email, :token, :type])
|> options_changeset()
|> apply_action(:parse)
end
def parse(%{token_hash: _} = attrs) do
{%{}, @token_hash_types}
|> cast(attrs, [:token_hash, :type, :options])
|> validate_required([:token_hash, :type])
|> options_changeset()
|> apply_action(:parse)
end
defp options_changeset(%Ecto.Changeset{valid?: false} = changeset), do: changeset
defp options_changeset(%Ecto.Changeset{} = changeset) do
if options = get_change(changeset, :options) do
{:ok, result} =
{%{}, @options_types}
|> cast(options, Map.keys(@options_types))
|> apply_action(:parse)
put_change(changeset, :options, result)
else
changeset
end
end
end