Packages
indieweb
0.0.65
0.0.66
0.0.65
0.0.64
0.0.63
0.0.62
0.0.61
0.0.60
0.0.59
0.0.58
0.0.56
0.0.55
0.0.54
0.0.53
0.0.51
0.0.50
0.0.49
0.0.48
0.0.47
0.0.46
0.0.42
0.0.41
0.0.40
0.0.39
0.0.38
0.0.37
0.0.36
0.0.35
0.0.34
0.0.33
0.0.32
0.0.31
0.0.30
0.0.29
0.0.28
0.0.27
0.0.26
0.0.25
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.3
0.0.2
0.0.1
Collection of common IndieWeb utilites like authorship resolution, Webmention, post type discovery and IndieAuth.
Current section
Files
Jump to
Current section
Files
lib/indieweb/auth/code.ex
defmodule IndieWeb.Auth.Code do
@moduledoc "Handles authentication codes for the IndieAuth flow."
@default_code_age 10 * 60
defmodule Adapter do
@moduledoc "Provides an abstraction regarding code actions for IndieAuth."
@callback generate() :: binary()
@callback generate_challenge(options :: keyword()) :: {binary(), binary(), binary()}
@callback persist(
code :: binary(),
client_id :: binary(),
redirect_uri :: binary(),
args :: map(),
options :: keyword()
) :: :ok | {:error, any()}
@callback persist_challenge(
code :: binary(),
challenge :: binary(),
method :: binary(),
options :: keyword()
) :: :ok | {:error, any()}
@callback destroy(
code :: binary(),
options :: keyword()
) :: :ok
@callback verify(
code :: binary(),
client_id :: binary(),
redirect_uri :: binary(),
options :: keyword()
) :: {:ok, map()} | {:error, any()}
@callback verify_challenge(
verifier :: binary(),
code :: binary(),
options :: keyword()
) :: :ok | {:error, any()}
end
@doc "Generates a code for IndieAuth based on the client_id, redirect_uri and any other extra parameters."
@spec generate(keyword()) :: binary()
def generate(options \\ []) do
adapter(options).generate()
end
@doc """
Stores a code for later verification.
Provided a `code`, a client's ID `client_id`, the URL that this should redirect
to `redirect_uri` as well as any arguments used to craft this authorization request in `params`, store said code and references to for later verification.
"""
@spec persist(binary(), binary(), binary(), map(), keyword()) :: :ok
def persist(code, client_id, redirect_uri, params \\ %{}, options \\ []) do
adapter(options).persist(code, client_id, redirect_uri, params, options)
end
@doc """
Verifies a code with the provided fields.
Confirms that a code `code` was created for the provided client's ID `client_id`,
the URL that this should redirect to `redirect_uri` as well as any arguments used
to craft this authorization request in `params`.
"""
@spec verify(binary(), binary(), binary(), keyword()) :: {:ok, map()} | {:error, any()}
def verify(code, client_id, redirect_uri, options \\ []) do
adapter(options).verify(code, client_id, redirect_uri, options)
end
@doc "Destroys all codes associated with the provided parameters."
@spec destroy(binary(), keyword()) :: :ok
def destroy(code, options \\ []) do
adapter(options).destroy(code, options)
end
@doc "Generates a PKCE-compatible challenge string for the provided parameters."
@spec generate_challenge(keyword()) :: {binary(), binary(), binary()}
def generate_challenge(options \\ []) do
adapter(options).generate_challenge(options)
end
@doc "Persists the provided challenge and method for the provided code."
@spec persist_challenge(binary(), binary(), binary(), keyword()) :: :ok | {:error, any()}
def persist_challenge(code, challenge, method, options \\ []) do
adapter(options).persist_challenge(code, challenge, method, options)
end
@doc "Provides the age, in seconds, of a code."
@spec age(keyword()) :: non_neg_integer()
def age(options \\ []) do
Keyword.get(options, :code_age, @default_code_age)
end
@spec verify_challenge(binary(), binary(), keyword()) ::
{:ok, code: binary()} | {:error, any()}
def verify_challenge(verifier, code, options \\ []) do
adapter(options).verify_challenge(verifier, code, options)
end
defp adapter(options) do
options
|> Keyword.get(:adapters, [])
|> Keyword.get(
:code,
IndieWeb.Auth.DefaultCodeAdapter
)
end
end