defmodule MvWeb.JoinConfirmController do @moduledoc """ Handles GET /confirm_join/:token for the public join flow (double opt-in). Renders a full HTML page with public header and hero layout (success, expired, or invalid). Calls a configurable callback (default Mv.Membership) so tests can stub the dependency. Public route; no authentication required. """ use MvWeb, :controller def confirm(conn, %{"token" => token}) when is_binary(token) do callback = Application.get_env(:mv, :join_confirm_callback, Mv.Membership) case callback.confirm_join_request(token, actor: nil) do {:ok, _request} -> success_response(conn) {:error, :token_expired} -> expired_response(conn) {:error, _} -> invalid_response(conn) end end def confirm(conn, _params), do: invalid_response(conn) defp success_response(conn) do conn |> assign_confirm_assigns(:success) |> put_view(MvWeb.JoinConfirmHTML) |> render("confirm.html") end defp expired_response(conn) do conn |> assign_confirm_assigns(:expired) |> put_view(MvWeb.JoinConfirmHTML) |> render("confirm.html") end defp invalid_response(conn) do conn |> put_status(404) |> assign_confirm_assigns(:invalid) |> put_view(MvWeb.JoinConfirmHTML) |> render("confirm.html") end defp assign_confirm_assigns(conn, result) do conn |> assign(:result, result) |> assign(:flash, conn.assigns[:flash] || conn.flash || %{}) end end