-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
306 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
defmodule Supabase.GoTrue.Schemas.SignInWithOTP do | ||
@moduledoc false | ||
|
||
use Supabase, :schema | ||
|
||
import Supabase.GoTrue.Validations | ||
|
||
@type options :: %__MODULE__.Options{ | ||
data: map(), | ||
email_redirect_to: String.t(), | ||
captcha_token: String.t(), | ||
channel: String.t(), | ||
should_create_user: boolean() | ||
} | ||
|
||
@type t :: %__MODULE__{ | ||
email: String.t(), | ||
phone: String.t(), | ||
options: options | ||
} | ||
|
||
@primary_key false | ||
embedded_schema do | ||
field :email, :string | ||
field :phone, :string | ||
|
||
embeds_one :options, Options, primary_key: false do | ||
field(:data, :map) | ||
field(:email_redirect_to, :string) | ||
field(:captcha_token, :string) | ||
field(:channel, :string, default: "sms") | ||
field(:should_create_user, :boolean, default: true) | ||
end | ||
end | ||
|
||
def to_sign_in_params(%__MODULE__{email: email} = signin, code_challenge, code_method) when not is_nil(email) do | ||
signin | ||
|> Map.take([:email]) | ||
|> Map.put(:data, signin.options.data) | ||
|> Map.put(:captcha_token, signin.options.captcha_token) | ||
|> Map.put(:create_user, signin.options.should_create_user) | ||
|> Map.put(:redirect_to, signin.options.email_redirect_to) | ||
|> Map.merge(%{code_challange: code_challenge, code_challenge_method: code_method}) | ||
end | ||
|
||
def to_sign_in_params(%__MODULE__{phone: phone} = signin, code_challenge, code_method) when not is_nil(phone) do | ||
signin | ||
|> Map.take([:phone]) | ||
|> Map.put(:data, signin.options.data) | ||
|> Map.put(:captcha_token, signin.options.captcha_token) | ||
|> Map.put(:create_user, signin.options.should_create_user) | ||
|> Map.put(:channel, signin.options.channel) | ||
|> Map.merge(%{code_challange: code_challenge, code_challenge_method: code_method}) | ||
end | ||
|
||
def to_sign_in_params(%__MODULE__{email: email} = signin) when not is_nil(email) do | ||
signin | ||
|> Map.take([:email]) | ||
|> Map.put(:data, signin.options.data) | ||
|> Map.put(:captcha_token, signin.options.captcha_token) | ||
|> Map.put(:create_user, signin.options.should_create_user) | ||
|> Map.put(:redirect_to, signin.options.email_redirect_to) | ||
end | ||
|
||
def to_sign_in_params(%__MODULE__{phone: phone} = signin) when not is_nil(phone) do | ||
signin | ||
|> Map.take([:phone]) | ||
|> Map.put(:data, signin.options.data) | ||
|> Map.put(:captcha_token, signin.options.captcha_token) | ||
|> Map.put(:create_user, signin.options.should_create_user) | ||
|> Map.put(:channel, signin.options.channel) | ||
end | ||
|
||
def parse(attrs) do | ||
%__MODULE__{} | ||
|> cast(attrs, ~w[email phone]a) | ||
|> validate_required_inclusion(~w[email phone]a) | ||
|> cast_embed(:options, with: &options_changeset/2, required: false) | ||
|> maybe_put_default_options() | ||
|> apply_action(:parse) | ||
end | ||
|
||
defp maybe_put_default_options(%{valid?: false} = c), do: c | ||
|
||
defp maybe_put_default_options(changeset) do | ||
if get_embed(changeset, :options) do | ||
changeset | ||
else | ||
put_embed(changeset, :options, %__MODULE__.Options{}) | ||
end | ||
end | ||
|
||
defp options_changeset(options, attrs) do | ||
cast(options, attrs, ~w[data email_redirect_to channel should_create_user captcha_token]a) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
defmodule Supabase.GoTrue.Schemas.VerifyOTP do | ||
@moduledoc false | ||
|
||
use Supabase, :schema | ||
|
||
@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 | ||
{%{}, @options_types} | ||
|> cast(options, Map.keys(@options_types)) | ||
|> apply_action(:parse) | ||
|> case do | ||
{:ok, option} -> put_change(changeset, :options, option) | ||
{:error, error_changeset} -> | ||
for {field, {err, info}} <- error_changeset.errors, reduce: changeset do | ||
changeset -> add_error(changeset, "options.#{field}", err, info) | ||
end | ||
end | ||
else | ||
changeset | ||
end | ||
end | ||
end |
Oops, something went wrong.