chore/update-deps (#236)

Reviewed-on: graham/towerops-web#236
This commit is contained in:
Graham McIntire 2026-04-15 13:13:36 -05:00 committed by graham
parent 2f3824cecc
commit f8b8082ee5

View file

@ -10,9 +10,6 @@ defmodule ToweropsWeb.Plugs.UpdateSessionActivity do
each session was last active. The update happens in a background task to avoid
slowing down requests.
"""
use Gettext, backend: ToweropsWeb.Gettext
import Phoenix.Controller, only: [put_flash: 3, redirect: 2]
import Plug.Conn
alias Towerops.Accounts
@ -28,48 +25,39 @@ defmodule ToweropsWeb.Plugs.UpdateSessionActivity do
@doc """
Updates the last_activity_at timestamp for the current browser session.
Checks for session inactivity timeout and logs out the user if the session
has been inactive for more than 30 minutes.
Checks for session inactivity timeout and revokes the token if the session
has been inactive for more than 30 minutes. All database work runs in a
background task so the request is not blocked.
When a timed-out session is detected, the token is deleted so the next
request will be unauthenticated and redirected to login by the auth pipeline.
Looks up the session by the token stored in the session cookie, then
updates the timestamp in a background task.
"""
def call(conn, _opts) do
case get_session(conn, :user_token) do
nil -> conn
token -> handle_session_activity(conn, token)
end
end
# Handle session activity check and timeout
defp handle_session_activity(conn, token) do
case check_session_activity(token) do
:active ->
# Session is active, update timestamp in background
Task.start(fn -> update_session_activity(token) end)
nil ->
conn
:timeout ->
# Session timed out due to inactivity
logout_inactive_session(conn, token)
:not_found ->
# Session not found, continue normally
token ->
live_socket_id = get_session(conn, :live_socket_id)
Task.start(fn -> handle_session_activity(token, live_socket_id) end)
conn
end
end
# Check if session is still active or has timed out
defp check_session_activity(token) do
# Runs in a background task: check activity and either touch or revoke the session
defp handle_session_activity(token, live_socket_id) do
case Accounts.get_browser_session_by_token_value(token) do
nil ->
:not_found
:ok
session ->
if session_timed_out?(session) do
:timeout
revoke_inactive_session(token, live_socket_id)
else
:active
Accounts.touch_browser_session(session)
end
end
end
@ -81,35 +69,12 @@ defmodule ToweropsWeb.Plugs.UpdateSessionActivity do
inactive_seconds > @inactivity_timeout_seconds
end
# Log out user due to inactivity timeout
defp logout_inactive_session(conn, token) do
# Delete the session token
# Revoke the token so the next request will be unauthenticated
defp revoke_inactive_session(token, live_socket_id) do
Accounts.delete_user_session_token(token)
# Broadcast logout to LiveView socket
if live_socket_id = get_session(conn, :live_socket_id) do
if live_socket_id do
ToweropsWeb.Endpoint.broadcast(live_socket_id, "disconnect", %{})
end
# Clear session and redirect to login
conn
|> configure_session(renew: true)
|> clear_session()
|> delete_resp_cookie("_towerops_web_user_remember_me")
|> put_flash(:info, gettext("Your session expired due to inactivity. Please log in again."))
|> redirect(to: "/users/log-in")
|> halt()
end
defp update_session_activity(token) do
case Accounts.get_browser_session_by_token_value(token) do
nil ->
# No browser session found (might be an old session from before this feature)
:ok
session ->
# Update activity timestamp
Accounts.touch_browser_session(session)
end
end
end