diff --git a/README.md b/README.md index 63fc9c9..770f7b8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The package can be installed by adding `phone_verification` to your list of depe def deps do [ {:jason, "~> 1.1"}, # or any other JSON library - {:phone_verification, "~> 0.1.0"} + {:phone_verification, "~> 0.3.0"} ] end ``` @@ -24,7 +24,8 @@ config :phone_verification, config :phone_verification, PhoneVerification.Provider.Authy, json_codec: Jason, - api_key: System.get_env("AUTHY_API_KEY") + api_key: System.get_env("AUTHY_API_KEY"), + mocks: %{} ``` ## Usage diff --git a/config/config.exs b/config/config.exs index 0b6e45d..857cb18 100644 --- a/config/config.exs +++ b/config/config.exs @@ -8,4 +8,6 @@ config :phone_verification, config :phone_verification, PhoneVerification.Provider.Authy, # json_codec: Jason, - api_key: System.get_env("AUTHY_API_KEY") + api_key: System.get_env("AUTHY_API_KEY"), + # example: %{ "+380001234567" => "0000", "+380001234568" => "1234" } + mocks: %{} diff --git a/lib/phone_verification.ex b/lib/phone_verification.ex index f0cf6ec..fab0dc0 100644 --- a/lib/phone_verification.ex +++ b/lib/phone_verification.ex @@ -7,6 +7,20 @@ defmodule PhoneVerification do Application.get_env(:phone_verification, key) end + @spec start(%{ + required(:phone_number) => PhoneVerification.PhoneNumber.t(), + required(:via) => :sms | :call, + optional(:locale) => String.t(), + optional(:code_length) => non_neg_integer(), + optional(:custom_code) => PhoneVerification.verification_code() + }) :: + {:ok, + %{ + message: String.t(), + carrier: String.t(), + seconds_to_expire: non_neg_integer() + }} + | {:error, %{message: String.t(), code: non_neg_integer()}} def start(params) do config(:default) |> Enum.into(%{}) @@ -14,6 +28,10 @@ defmodule PhoneVerification do |> config(:provider).start() end + @spec check(%{ + required(:phone_number) => PhoneVerification.PhoneNumber.t(), + required(:verification_code) => PhoneVerification.verification_code() + }) :: {:ok, %{message: String.t()}} | {:error, %{message: String.t(), code: String.t()}} def check(params) do config(:provider).check(params) end diff --git a/lib/phone_verification/provider/authy.ex b/lib/phone_verification/provider/authy.ex index d433bb9..9368092 100644 --- a/lib/phone_verification/provider/authy.ex +++ b/lib/phone_verification/provider/authy.ex @@ -2,17 +2,33 @@ defmodule PhoneVerification.Provider.Authy do @behaviour PhoneVerification.Provider @base_url "https://api.authy.com/protected/json/phones/verification/" + # actually, it can be infinity, but we have to return a number + @expiration_time_for_mock_phone_number_security_code 600 + @mock_carrier "life:) - Astelit" @supported_keys [:phone_number, :country_code, :via, :locale, :code_length, :custom_code] @impl true - def start(params) do - request(:post, "start", transform_params(params, @supported_keys)) + def start(%{phone_number: phone_number} = params) do + if mock_number?(phone_number) do + {:ok, + %{ + seconds_to_expire: @expiration_time_for_mock_phone_number_security_code, + message: "Requested verification using mock: #{phone_number}.", + carrier: @mock_carrier + }} + else + request(:post, "start", transform_params(params, @supported_keys)) + end end @supported_keys [:phone_number, :country_code, :verification_code] @impl true - def check(params) do - request(:get, "check", transform_params(params, @supported_keys)) + def check(%{phone_number: phone_number} = params) do + if mock_number?(phone_number) do + check_mock_number(params) + else + request(:get, "check", transform_params(params, @supported_keys)) + end end defp request(method, action, params) do @@ -77,4 +93,16 @@ defmodule PhoneVerification.Provider.Authy do |> PhoneVerification.config() |> Keyword.fetch!(key) end + + defp mock_number?(phone_number) do + !is_nil(config(:mocks)[to_string(phone_number)]) + end + + defp check_mock_number(%{phone_number: phone_number, verification_code: code}) do + if config(:mocks)[to_string(phone_number)] == code do + {:ok, %{message: "Verification code is correct."}} + else + {:error, %{message: "Verification code is incorrect", code: 60_022}} + end + end end diff --git a/mix.exs b/mix.exs index 9bb1ef7..7f17743 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule PhoneVerification.MixProject do def project do [ app: :phone_verification, - version: "0.2.0", + version: "0.3.0", elixir: "~> 1.3", start_permanent: Mix.env() == :prod, description: description(),