towerops/lib/towerops_web/controllers/user_registration_controller.ex

86 lines
2.7 KiB
Elixir

defmodule ToweropsWeb.UserRegistrationController do
@moduledoc false
use ToweropsWeb, :controller
alias Towerops.Accounts
alias Towerops.Accounts.User
alias Towerops.Organizations
alias ToweropsWeb.UserAuth
def new(conn, params) do
# Check if registering via invitation
invitation_token = params["invitation_token"] || params["token"]
invitation = invitation_token && Organizations.get_invitation_by_token(invitation_token)
changeset = Accounts.change_user_registration(%User{})
render(conn, :new,
form: Phoenix.Component.to_form(changeset, as: "user"),
invitation: invitation,
invitation_token: invitation_token
)
end
def create(conn, %{"user" => user_params}) do
invitation_token = user_params["invitation_token"] || conn.params["invitation_token"]
if invitation_token do
# Registration via invitation - don't create personal org
create_via_invitation(conn, user_params, invitation_token)
else
# Normal registration - create personal org
create_with_organization(conn, user_params)
end
end
defp create_with_organization(conn, user_params) do
case Accounts.register_user_with_organization(user_params) do
{:ok, user} ->
conn
|> put_flash(:info, t("Account created successfully."))
|> UserAuth.log_in_user(user)
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, :new,
form: Phoenix.Component.to_form(changeset, as: "user"),
invitation: nil,
invitation_token: nil
)
end
end
defp create_via_invitation(conn, user_params, invitation_token) do
with {:ok, invitation} <- get_valid_invitation(invitation_token),
{:ok, user} <- Accounts.register_user(user_params),
{:ok, _membership} <- Organizations.accept_invitation(invitation, user.id) do
conn
|> put_flash(:info, t("Account created successfully. Welcome to %{org}!", org: invitation.organization.name))
|> UserAuth.log_in_user(user)
else
{:error, :invalid_invitation} ->
changeset = Accounts.change_user_registration(%User{}, user_params)
conn
|> put_flash(:error, t("Invalid or expired invitation link."))
|> render(:new,
form: Phoenix.Component.to_form(changeset, as: "user"),
invitation: nil,
invitation_token: nil
)
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, :new,
form: Phoenix.Component.to_form(changeset, as: "user"),
invitation_token: invitation_token
)
end
end
defp get_valid_invitation(token) do
case Organizations.get_invitation_by_token(token) do
nil -> {:error, :invalid_invitation}
invitation -> {:ok, invitation}
end
end
end