defmodule <%= inspect @module %> do @moduledoc """ Authentication controller generated by Caravela from <%= inspect @domain_module %>. Regenerate with `mix caravela.gen.auth <%= inspect @domain_module %>`. Custom code placed below the `# --- CUSTOM ---` marker is preserved. """ use Phoenix.Controller, formats: [:json] alias <%= inspect @auth_module %>, as: Auth def register(conn, params) do case Auth.register(params, request_context(conn)) do {:ok, user} -> conn |> put_status(:created) |> json(%{id: user.id, email: user.email}) {:error, %Ecto.Changeset{} = changeset} -> conn |> put_status(:unprocessable_entity) |> json(%{errors: translate_errors(changeset)}) end end def login(conn, %{"email" => email, "password" => password}) do case Auth.login(email, password, request_context(conn)) do {:ok, _user, token} -> conn |> Plug.Conn.put_session(:user_token, token) |> json(%{token: Base.url_encode64(token, padding: false)}) {:error, reason} -> conn |> put_status(:unauthorized) |> json(%{error: Atom.to_string(reason)}) end end def logout(conn, _params) do token = Plug.Conn.get_session(conn, :user_token) if token, do: Auth.logout(token) conn |> Plug.Conn.delete_session(:user_token) |> send_resp(:no_content, "") end <%= if @reset? do %> def request_password_reset(conn, %{"email" => email}) do _ = Auth.request_password_reset(email, request_context(conn)) # Always respond 204 to avoid leaking which emails exist. send_resp(conn, :no_content, "") end def reset_password(conn, %{"token" => token, "password" => password}) do case Auth.reset_password(token, password) do {:ok, _user} -> send_resp(conn, :no_content, "") {:error, _} -> conn |> put_status(:bad_request) |> json(%{error: "invalid_token"}) end end <% end %><%= if @confirm? do %> def confirm_email(conn, %{"token" => token}) do case Auth.confirm_email(token) do {:ok, _user} -> send_resp(conn, :no_content, "") {:error, _} -> conn |> put_status(:bad_request) |> json(%{error: "invalid_token"}) end end <% end %> defp request_context(conn) do %{ current_user: conn.assigns[:current_user]<%= if @multi_tenant do %>, tenant_id: conn.assigns[:tenant_id]<% end %> } end defp translate_errors(%Ecto.Changeset{} = changeset) do Ecto.Changeset.traverse_errors(changeset, fn {msg, opts} -> Enum.reduce(opts, msg, fn {k, v}, acc -> String.replace(acc, "%{#{k}}", to_string(v)) end) end) end <%= @custom_marker %>