Packages
ash_authentication
5.0.0-rc.6
5.0.0-rc.12
5.0.0-rc.11
5.0.0-rc.10
5.0.0-rc.9
5.0.0-rc.8
5.0.0-rc.7
5.0.0-rc.6
5.0.0-rc.5
5.0.0-rc.4
5.0.0-rc.3
5.0.0-rc.2
5.0.0-rc.1
5.0.0-rc.0
4.14.1
4.14.0
4.13.7
4.13.6
4.13.5
4.13.4
4.13.3
4.13.2
retired
4.13.1
retired
4.13.0
4.12.0
4.11.0
4.10.0
4.9.9
4.9.8
4.9.7
4.9.6
4.9.5
4.9.4
4.9.3
4.9.2
4.9.1
4.9.0
4.8.7
4.8.6
4.8.5
4.8.3
4.8.2
4.8.1
4.8.0
4.7.6
4.7.5
4.7.4
4.7.3
4.7.2
4.7.1
4.7.0
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.6
4.5.5
4.5.4
4.5.3
4.5.2
4.5.1
4.5.0
4.4.9
4.4.8
4.4.7
4.4.6
4.4.5
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.12
4.3.11
4.3.10
4.3.9
4.3.8
4.3.7
4.3.6
4.3.5
4.3.4
4.3.3
4.3.2
4.3.1
4.3.0
4.2.7
4.2.6
4.2.5
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.4
4.0.3
4.0.2
4.0.1
4.0.0
4.0.0-rc.6
4.0.0-rc.5
4.0.0-rc.3
4.0.0-rc.2
4.0.0-rc.1
4.0.0-rc.0
3.12.4
3.12.3
3.12.2
3.12.1
3.12.0
3.11.16
3.11.15
3.11.14
3.11.13
3.11.12
3.11.11
3.11.10
3.11.9
3.11.8
3.11.7
3.11.6
3.11.5
3.11.4
3.11.3
3.11.2
3.11.1
3.11.0
3.10.8
3.10.7
3.10.6
3.10.5
3.10.4
3.10.3
3.10.2
3.10.1
3.10.0
3.9.6
3.9.5
3.9.4
3.9.3
3.9.2
3.9.1
3.9.0
3.8.0
3.7.9
3.7.8
3.7.6
3.7.5
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.1
3.6.0
3.5.3
3.5.2
3.5.1
3.5.0
3.3.1
3.3.0
3.2.2
3.2.1
3.2.0
3.1.0
3.0.3
Authentication extension for the Ash Framework.
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/ash_authentication/strategies/webauthn/strategy.ex
# SPDX-FileCopyrightText: 2026 Alembic Pty Ltd
#
# SPDX-License-Identifier: MIT
defimpl AshAuthentication.Strategy, for: AshAuthentication.Strategy.WebAuthn do
@moduledoc """
Implementation of `AshAuthentication.Strategy` for `AshAuthentication.Strategy.WebAuthn`.
"""
alias AshAuthentication.{Info, Strategy, Strategy.WebAuthn}
alias Plug.Conn
@type phase ::
:registration_challenge
| :register
| :authentication_challenge
| :sign_in
| :add_credential_challenge
| :add_credential
@doc false
@spec name(WebAuthn.t()) :: atom
def name(strategy), do: strategy.name
@doc false
@spec phases(WebAuthn.t()) :: [phase]
def phases(strategy) do
auth_phases = [:authentication_challenge, :sign_in]
add_phases = [:add_credential_challenge, :add_credential]
if strategy.registration_enabled? do
[:registration_challenge, :register] ++ auth_phases ++ add_phases
else
auth_phases ++ add_phases
end
end
@doc false
@spec actions(WebAuthn.t()) :: [atom]
def actions(strategy) do
if strategy.registration_enabled? do
[:register, :sign_in, :add_credential]
else
[:sign_in, :add_credential]
end
end
@doc false
@spec method_for_phase(WebAuthn.t(), phase) :: Strategy.http_method()
def method_for_phase(_, :registration_challenge), do: :get
def method_for_phase(_, :authentication_challenge), do: :get
def method_for_phase(_, :add_credential_challenge), do: :get
def method_for_phase(_, :register), do: :post
def method_for_phase(_, :sign_in), do: :post
def method_for_phase(_, :add_credential), do: :post
@doc false
@spec routes(WebAuthn.t()) :: [Strategy.route()]
def routes(strategy) do
subject_name = Info.authentication_subject_name!(strategy.resource)
strategy
|> phases()
|> Enum.map(fn phase ->
path =
[subject_name, strategy.name, phase]
|> Enum.map(&to_string/1)
|> Path.join()
{"/#{path}", phase}
end)
end
@doc false
@spec plug(WebAuthn.t(), phase, Conn.t()) :: Conn.t()
def plug(strategy, :registration_challenge, conn),
do: WebAuthn.Plug.registration_challenge(conn, strategy)
def plug(strategy, :register, conn),
do: WebAuthn.Plug.register(conn, strategy)
def plug(strategy, :authentication_challenge, conn),
do: WebAuthn.Plug.authentication_challenge(conn, strategy)
def plug(strategy, :sign_in, conn),
do: WebAuthn.Plug.sign_in(conn, strategy)
def plug(strategy, :add_credential_challenge, conn),
do: WebAuthn.Plug.add_credential_challenge(conn, strategy)
def plug(strategy, :add_credential, conn),
do: WebAuthn.Plug.add_credential(conn, strategy)
@doc false
@spec action(WebAuthn.t(), atom, map, keyword) :: {:ok, any} | {:error, any}
def action(strategy, :register, params, options),
do: WebAuthn.Actions.register(strategy, params, options)
def action(strategy, :sign_in, params, options),
do: WebAuthn.Actions.sign_in(strategy, params, options)
def action(strategy, :add_credential, params, options),
do: WebAuthn.Actions.add_credential(strategy, params, options)
@doc false
@spec tokens_required?(WebAuthn.t()) :: boolean
def tokens_required?(_), do: true
end