defmodule ToweropsWeb.UserSettingsLive.SessionManager do @moduledoc """ Handles browser session and mobile device session management. """ use Gettext, backend: ToweropsWeb.Gettext import ToweropsWeb.GettextHelpers alias Towerops.Accounts alias Towerops.MobileSessions @doc """ Revokes a mobile device session. """ def revoke_mobile_device(socket, session_id) do case MobileSessions.revoke_session(session_id) do {:ok, _} -> socket |> Phoenix.LiveView.put_flash(:info, t_auth("Mobile device removed successfully.")) |> assign_mobile_sessions() {:error, _} -> Phoenix.LiveView.put_flash(socket, :error, t_auth("Failed to remove mobile device.")) end end @doc """ Toggles alert preferences for a mobile device. """ def toggle_device_alerts(socket, session_id, enabled) do enabled_bool = enabled == "true" case MobileSessions.update_alert_preferences(session_id, %{alerts_enabled: enabled_bool}) do {:ok, _} -> message = if enabled_bool, do: t_auth("Alerts enabled for device"), else: t_auth("Alerts disabled for device") socket |> Phoenix.LiveView.put_flash(:info, message) |> assign_mobile_sessions() {:error, _} -> Phoenix.LiveView.put_flash(socket, :error, t_auth("Failed to update alert preferences.")) end end @doc """ Revokes a browser session. """ def revoke_session(socket, session_id) do user = socket.assigns.current_scope.user current_token_id = get_current_token_id(socket) case Accounts.revoke_browser_session(session_id, user.id, current_token_id) do {:ok, _} -> socket |> Phoenix.LiveView.put_flash(:info, t_auth("Session revoked successfully.")) |> assign_browser_sessions() {:error, :self_revoke} -> Phoenix.LiveView.put_flash(socket, :error, t_auth("You cannot revoke your current session.")) {:error, :not_found} -> Phoenix.LiveView.put_flash(socket, :error, t_auth("Session not found.")) {:error, _} -> Phoenix.LiveView.put_flash(socket, :error, t_auth("Failed to revoke session.")) end end @doc """ Shows the revoke all sessions confirmation modal. """ def show_revoke_all_modal(socket) do Phoenix.Component.assign(socket, :show_revoke_all_modal, true) end @doc """ Cancels revoking all sessions. """ def cancel_revoke_all(socket) do Phoenix.Component.assign(socket, :show_revoke_all_modal, false) end @doc """ Confirms and revokes all other sessions except the current one. """ def confirm_revoke_all(socket) do user = socket.assigns.current_scope.user current_token_id = get_current_token_id(socket) {count, _} = Accounts.revoke_all_other_sessions(user.id, current_token_id) socket |> Phoenix.LiveView.put_flash(:info, t_auth("Revoked %{count} other session(s) successfully.", count: count)) |> Phoenix.Component.assign(:show_revoke_all_modal, false) |> assign_browser_sessions() end @doc """ Assigns mobile sessions to socket. """ def assign_mobile_sessions(socket) do user = socket.assigns.current_scope.user Phoenix.Component.assign(socket, :mobile_sessions, MobileSessions.list_user_sessions(user.id)) end @doc """ Assigns browser sessions to socket. """ def assign_browser_sessions(socket) do user = socket.assigns.current_scope.user sessions = Accounts.list_active_browser_sessions(user.id) Phoenix.Component.assign(socket, :browser_sessions, sessions) end @doc """ Gets the current token ID from socket assigns. """ def get_current_token_id(%{assigns: %{current_token: token}}) when is_binary(token) do Accounts.get_user_token_id_by_value(token) end def get_current_token_id(_), do: nil end