Add a way to force user logout
The idea is to remove the session and also disconnect all liveviews
This commit is contained in:
parent
2564b1b727
commit
b6524131c1
6 changed files with 49 additions and 0 deletions
|
@ -6,6 +6,7 @@ defmodule RealEstate.Accounts do
|
||||||
import Ecto.Query, warn: false
|
import Ecto.Query, warn: false
|
||||||
alias RealEstate.Repo
|
alias RealEstate.Repo
|
||||||
alias RealEstate.Accounts.{User, UserToken, UserNotifier}
|
alias RealEstate.Accounts.{User, UserToken, UserNotifier}
|
||||||
|
alias RealEstateWeb.UserAuth
|
||||||
|
|
||||||
## Database getters
|
## Database getters
|
||||||
|
|
||||||
|
@ -97,6 +98,21 @@ defmodule RealEstate.Accounts do
|
||||||
|> Repo.insert()
|
|> Repo.insert()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def logout_user(%User{} = user) do
|
||||||
|
# Delete all user tokens
|
||||||
|
Repo.delete_all(UserToken.user_and_contexts_query(user, :all))
|
||||||
|
|
||||||
|
# Broadcast to all liveviews to immediately disconnect the user
|
||||||
|
RealEstateWeb.Endpoint.broadcast_from(
|
||||||
|
self(),
|
||||||
|
UserAuth.pubsub_topic(),
|
||||||
|
"logout_user",
|
||||||
|
%{
|
||||||
|
user: user
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns an `%Ecto.Changeset{}` for tracking user changes.
|
Returns an `%Ecto.Changeset{}` for tracking user changes.
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,19 @@ defmodule RealEstateWeb do
|
||||||
|
|
||||||
unquote(view_helpers())
|
unquote(view_helpers())
|
||||||
import RealEstateWeb.LiveHelpers
|
import RealEstateWeb.LiveHelpers
|
||||||
|
|
||||||
|
alias RealEstate.Accounts.User
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info(%{event: "logout_user", payload: %{user: %User{id: id}}}, socket) do
|
||||||
|
with %User{id: ^id} <- socket.assigns.current_user do
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> redirect(to: Routes.user_session_path(socket, :force_logout))}
|
||||||
|
else
|
||||||
|
_any -> {:noreply, socket}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ defmodule RealEstateWeb.UserAuth do
|
||||||
alias RealEstate.Accounts
|
alias RealEstate.Accounts
|
||||||
alias RealEstateWeb.Router.Helpers, as: Routes
|
alias RealEstateWeb.Router.Helpers, as: Routes
|
||||||
|
|
||||||
|
@pubsub_topic "user_updates"
|
||||||
|
|
||||||
# Make the remember me cookie valid for 60 days.
|
# Make the remember me cookie valid for 60 days.
|
||||||
# If you want bump or reduce this value, also change
|
# If you want bump or reduce this value, also change
|
||||||
# the token expiry itself in UserToken.
|
# the token expiry itself in UserToken.
|
||||||
|
@ -139,6 +141,11 @@ defmodule RealEstateWeb.UserAuth do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the pubsub topic name for receiving notifications when a user updated
|
||||||
|
"""
|
||||||
|
def pubsub_topic, do: @pubsub_topic
|
||||||
|
|
||||||
defp maybe_store_return_to(%{method: "GET"} = conn) do
|
defp maybe_store_return_to(%{method: "GET"} = conn) do
|
||||||
%{request_path: request_path, query_string: query_string} = conn
|
%{request_path: request_path, query_string: query_string} = conn
|
||||||
return_to = if query_string == "", do: request_path, else: request_path <> "?" <> query_string
|
return_to = if query_string == "", do: request_path, else: request_path <> "?" <> query_string
|
||||||
|
|
|
@ -23,4 +23,13 @@ defmodule RealEstateWeb.UserSessionController do
|
||||||
|> put_flash(:info, "Logged out successfully.")
|
|> put_flash(:info, "Logged out successfully.")
|
||||||
|> UserAuth.log_out_user()
|
|> UserAuth.log_out_user()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def force_logout(conn, _params) do
|
||||||
|
conn
|
||||||
|
|> put_flash(
|
||||||
|
:info,
|
||||||
|
"You were logged out. Please login again to continue using our application."
|
||||||
|
)
|
||||||
|
|> UserAuth.log_out_user()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@ defmodule RealEstateWeb.LiveHelpers do
|
||||||
alias RealEstate.Accounts
|
alias RealEstate.Accounts
|
||||||
alias RealEstate.Accounts.User
|
alias RealEstate.Accounts.User
|
||||||
alias RealEstateWeb.Router.Helpers, as: Routes
|
alias RealEstateWeb.Router.Helpers, as: Routes
|
||||||
|
alias RealEstateWeb.UserAuth
|
||||||
import Phoenix.LiveView.Helpers
|
import Phoenix.LiveView.Helpers
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -26,6 +27,8 @@ defmodule RealEstateWeb.LiveHelpers do
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_defaults(session, socket) do
|
def assign_defaults(session, socket) do
|
||||||
|
RealEstateWeb.Endpoint.subscribe(UserAuth.pubsub_topic())
|
||||||
|
|
||||||
socket =
|
socket =
|
||||||
assign_new(socket, :current_user, fn ->
|
assign_new(socket, :current_user, fn ->
|
||||||
find_current_user(session)
|
find_current_user(session)
|
||||||
|
|
|
@ -76,6 +76,7 @@ defmodule RealEstateWeb.Router do
|
||||||
scope "/", RealEstateWeb do
|
scope "/", RealEstateWeb do
|
||||||
pipe_through [:browser]
|
pipe_through [:browser]
|
||||||
|
|
||||||
|
get "/users/force_logout", UserSessionController, :force_logout
|
||||||
delete "/users/log_out", UserSessionController, :delete
|
delete "/users/log_out", UserSessionController, :delete
|
||||||
get "/users/confirm", UserConfirmationController, :new
|
get "/users/confirm", UserConfirmationController, :new
|
||||||
post "/users/confirm", UserConfirmationController, :create
|
post "/users/confirm", UserConfirmationController, :create
|
||||||
|
|
Loading…
Reference in a new issue