Current section
Files
Jump to
Current section
Files
lib/maat_feather_web/controllers/auth_controller.ex
defmodule MaatFeatherWeb.AuthController do
@moduledoc """
Controller for authentication.
"""
use MaatFeatherWeb, :controller
alias MaatFeather.Users
alias MaatFeather.Users.User
alias MaatFeather.Auth.{Token, TOTP}
alias MaatFeatherWeb.UserView
action_fallback MaatFeatherWeb.FallbackController
@doc """
Signin a user to the system.
"""
def signin(conn, %{"email" => email, "password" => password} = params) do
with %User{} = user <- Users.get_user_by!(email: email),
true <- Argon2.verify_pass(password, user.password_hash) do
unless user.has_mfa do
{:ok, access_token, _claims} = Token.encode(user)
conn
|> put_status(:ok)
|> json(%{access_token: access_token})
else
if TOTP.is_valid?(user.secret_key, params["totp_token"]) do
{:ok, access_token, _claims} = Token.encode(user)
conn
|> put_status(:ok)
|> json(%{access_token: access_token})
else
{:error, :unauthorized}
end
end
else
_ ->
{:error, :unauthorized}
end
end
def refresh_token(%Plug.Conn{assigns: %{access_token: access_token}} = conn, _params) do
with {:ok, {_old_token, _old_claims}, {new_token, _new_claims}} <- Token.refresh(access_token) do
conn
|> put_status(:ok)
|> json(%{refresh_token: new_token})
else
{:error, message} ->
conn
|> put_status(:unauthorized)
|> json(%{errors: %{message: message}})
end
end
def refresh_token(_conn, _params), do: {:error, :unauthorized}
def totp_qrcode(%Plug.Conn{assigns: %{user: %{"sub" => address}}} = conn, _params) do
case Users.get_user!(address) do
nil ->
{:error, :not_found}
user ->
qrcode = TOTP.gen_qrcode(user.email, user.secret_key)
conn
|> put_status(:ok)
|> json(%{qrcode: qrcode})
end
end
@doc """
Get user profile.
"""
def profile(
%Plug.Conn{assigns: %{user: %{"sub" => address}}} = conn,
_params
) do
case Users.get_user!(address) do
nil ->
{:error, :not_found}
user ->
conn
|> put_view(UserView)
|> put_status(:ok)
|> render("show.json", %{user: user})
end
end
def profile(_conn, _params), do: {:error, :unauthorized}
end