fix: org switching now correctly updates session

The select_org LiveView event was updating default_organization_id in
the database but not the session's current_organization_id. Since
load_default_organization prioritizes the session value, users would
always get redirected back to the stale org.

Replaced with a controller POST action that updates both the session
and DB default before redirecting.
This commit is contained in:
Graham McIntire 2026-03-04 17:04:49 -06:00
parent c10394808a
commit c56496f7cc
No known key found for this signature in database
4 changed files with 35 additions and 23 deletions

View file

@ -114,6 +114,23 @@ defmodule ToweropsWeb.UserSessionController do
end
end
def switch_org(conn, %{"org_id" => org_id}) do
user = conn.assigns.current_scope.user
membership = Towerops.Organizations.get_membership(org_id, user.id)
if membership do
{:ok, _user} = Accounts.update_user_profile(user, %{default_organization_id: org_id})
conn
|> put_session(:current_organization_id, org_id)
|> redirect(to: ~p"/dashboard")
else
conn
|> put_flash(:error, t("You don't have access to this organization."))
|> redirect(to: ~p"/orgs")
end
end
def delete(conn, _params) do
conn
|> put_flash(:info, t("Logged out successfully."))

View file

@ -2,7 +2,6 @@ defmodule ToweropsWeb.OrgLive.Index do
@moduledoc false
use ToweropsWeb, :live_view
alias Towerops.Accounts
alias Towerops.Organizations
@impl true
@ -20,14 +19,4 @@ defmodule ToweropsWeb.OrgLive.Index do
def handle_params(_params, _url, socket) do
{:noreply, socket}
end
@impl true
def handle_event("select_org", %{"org-id" => org_id}, socket) do
user = socket.assigns.current_scope.user
# Update user's default organization
{:ok, _user} = Accounts.update_user_profile(user, %{default_organization_id: org_id})
{:noreply, push_navigate(socket, to: ~p"/dashboard")}
end
end

View file

@ -12,20 +12,25 @@
</.header>
<div :if={@organizations != []} class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
<button
<form
:for={org <- @organizations}
type="button"
phx-click="select_org"
phx-value-org-id={org.id}
class="relative overflow-hidden rounded-lg border border-gray-200 bg-white p-6 shadow-sm hover:shadow-md transition-shadow dark:border-white/10 dark:bg-gray-800/50 cursor-pointer text-left"
method="post"
action={~p"/orgs/switch"}
>
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">{org.name}</h2>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
{Enum.find(org.memberships, &(&1.user_id == @current_scope.user.id)).role
|> to_string()
|> String.capitalize()}
</p>
</button>
<input type="hidden" name="_csrf_token" value={Phoenix.Controller.get_csrf_token()} />
<input type="hidden" name="org_id" value={org.id} />
<button
type="submit"
class="relative w-full overflow-hidden rounded-lg border border-gray-200 bg-white p-6 shadow-sm hover:shadow-md transition-shadow dark:border-white/10 dark:bg-gray-800/50 cursor-pointer text-left"
>
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">{org.name}</h2>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
{Enum.find(org.memberships, &(&1.user_id == @current_scope.user.id)).role
|> to_string()
|> String.capitalize()}
</p>
</button>
</form>
</div>
<div :if={@organizations == []} class="text-center py-16">

View file

@ -270,6 +270,7 @@ defmodule ToweropsWeb.Router do
get "/users/sudo-verify", UserSudoController, :new
post "/users/sudo-verify", UserSudoController, :verify
post "/orgs/switch", UserSessionController, :switch_org
end
## Admin routes (superuser only)