Allow user to logout from Livebook app (#2961)

This commit is contained in:
Alexandre de Souza 2025-03-25 12:25:55 -03:00 committed by GitHub
parent e52ed86aee
commit 78aebde2ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 57 additions and 13 deletions

View file

@ -274,4 +274,32 @@ defmodule LivebookWeb.SessionHelpers do
Livebook.Session.register_file(session_pid, path, key)
end
end
@logout_topic "logout"
@doc """
Subscribes to #{@logout_topic} topic.
"""
@spec subscribe_to_logout() :: :ok | {:error, term()}
def subscribe_to_logout do
Phoenix.PubSub.subscribe(Livebook.PubSub, @logout_topic)
end
@doc """
Shows the confirmation modal to logout user from Livebook.
"""
@spec confirm_logout(Socket.t()) :: Socket.t()
def confirm_logout(socket) do
on_confirm = fn socket ->
Phoenix.PubSub.broadcast(Livebook.PubSub, @logout_topic, :logout)
put_flash(socket, :info, "Livebook is logging out. You will be redirected soon.")
end
confirm(socket, on_confirm,
title: "Log out",
description: "Are you sure you want to log out Livebook now?",
confirm_text: "Log out",
confirm_icon: "logout-box-line"
)
end
end

View file

@ -140,6 +140,12 @@ defmodule LivebookWeb.AppSessionLive do
<span>Debug</span>
</.link>
</.menu_item>
<.menu_item :if={Livebook.Config.logout_enabled?() and @current_user.email != nil}>
<button phx-click="logout" role="menuitem">
<.remix_icon icon="logout-box-line" />
<span>Logout</span>
</button>
</.menu_item>
</.menu>
</div>
<div data-el-js-view-iframes phx-update="ignore" id="js-view-iframes"></div>

View file

@ -41,9 +41,17 @@ defmodule LivebookWeb.AppAuthHook do
#
def on_mount(:default, %{"slug" => slug}, session, socket) do
if connected?(socket) do
LivebookWeb.SessionHelpers.subscribe_to_logout()
end
livebook_authenticated? = livebook_authenticated?(session, socket)
socket = assign(socket, livebook_authenticated?: livebook_authenticated?)
socket =
socket
|> assign(livebook_authenticated?: livebook_authenticated?)
|> attach_hook(:logout, :handle_info, &handle_info/2)
|> attach_hook(:logout, :handle_event, &handle_event/3)
case Livebook.Apps.fetch_settings(slug) do
{:ok, %{access_type: :public} = app_settings} ->
@ -70,6 +78,18 @@ defmodule LivebookWeb.AppAuthHook do
LivebookWeb.AuthPlug.authenticated?(session, uri.port)
end
defp handle_info(:logout, socket) do
{:halt, redirect(socket, to: ~p"/logout")}
end
defp handle_info(_event, socket), do: {:cont, socket}
defp handle_event("logout", %{}, socket) do
{:halt, LivebookWeb.SessionHelpers.confirm_logout(socket)}
end
defp handle_event(_event, _params, socket), do: {:cont, socket}
defp has_valid_token?(socket, app_settings) do
connect_params = get_connect_params(socket) || %{}

View file

@ -9,6 +9,7 @@ defmodule LivebookWeb.SidebarHook do
def on_mount(:default, _params, _session, socket) do
if connected?(socket) do
Livebook.Hubs.Broadcasts.subscribe([:crud, :connection])
LivebookWeb.SessionHelpers.subscribe_to_logout()
Phoenix.PubSub.subscribe(Livebook.PubSub, "sidebar")
end
@ -67,18 +68,7 @@ defmodule LivebookWeb.SidebarHook do
end
defp handle_event("logout", _params, socket) do
on_confirm = fn socket ->
Phoenix.PubSub.broadcast(Livebook.PubSub, "sidebar", :logout)
put_flash(socket, :info, "Livebook is logging out. You will be redirected soon.")
end
{:halt,
confirm(socket, on_confirm,
title: "Log out",
description: "Are you sure you want to log out Livebook now?",
confirm_text: "Log out",
confirm_icon: "logout-box-line"
)}
{:halt, LivebookWeb.SessionHelpers.confirm_logout(socket)}
end
defp handle_event(_event, _params, socket), do: {:cont, socket}