defmodule ToweropsWeb.Admin.UserLive.Index do @moduledoc """ Admin interface for viewing and managing users. """ use ToweropsWeb, :live_view alias Towerops.Admin alias Towerops.Admin.AuditLogger @impl true def mount(_params, _session, socket) do users = Admin.list_all_users() ip = get_connect_info_ip(socket) admin = socket.assigns.current_scope.superuser || socket.assigns.current_scope.user # Log admin viewing user data user_ids = Enum.map(users, & &1.id) AuditLogger.log_event("user_data_viewed", nil, actor_id: admin.id, metadata: %{ admin_page: "user_list", users_count: length(users) }, data_accessed: %{ user_ids: user_ids, fields: ["id", "email", "name", "is_superuser", "confirmed_at"] } ) {:ok, socket |> assign(:page_title, t("All Users")) |> assign(:timezone, socket.assigns.current_scope.timezone) |> assign(:users, users) |> assign(:client_ip, ip)} end @impl true def handle_event("impersonate", %{"id" => user_id}, socket) do {:noreply, redirect(socket, to: ~p"/admin/impersonate/#{user_id}")} end @impl true def handle_event("delete_user", %{"id" => user_id}, socket) do superuser = socket.assigns.current_scope.superuser || socket.assigns.current_scope.user ip = socket.assigns.client_ip case Admin.delete_user(user_id, superuser.id, ip) do {:ok, _} -> {:noreply, socket |> put_flash(:info, t_admin("User deleted successfully")) |> assign(:users, Admin.list_all_users())} {:error, _} -> {:noreply, put_flash(socket, :error, t_admin("Failed to delete user"))} end end defp get_connect_info_ip(socket) do case get_connect_info(socket, :peer_data) do %{address: address} -> to_string(:inet_parse.ntoa(address)) _ -> "unknown" end end end