Skip to content

Commit 0b19cd4

Browse files
Fix with pattern matching and fresh game reloads
1 parent 9ba1bfc commit 0b19cd4

File tree

1 file changed

+39
-30
lines changed
  • copi.owasp.org/lib/copi_web/live/player_live

1 file changed

+39
-30
lines changed

copi.owasp.org/lib/copi_web/live/player_live/show.ex

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -124,53 +124,62 @@ defmodule CopiWeb.PlayerLive.Show do
124124
end
125125
end
126126

127-
CopiWeb.Endpoint.broadcast(topic(game.id), "game:updated", game)
127+
# Reload fresh game record after continue vote mutations
128+
{:ok, updated_game} = Copi.Cornucopia.Game.find(game_id)
128129

129-
{:noreply, assign(socket, :game, game)}
130+
CopiWeb.Endpoint.broadcast(topic(updated_game.id), "game:updated", updated_game)
131+
132+
{:noreply, assign(socket, :game, updated_game)}
130133
end
131134
else
132-
{:noreply, socket}
135+
{:error, _reason} -> {:noreply, socket}
133136
end
134137
end
135138

136139
@impl true
137140
def handle_event("toggle_vote", %{"dealt_card_id" => dealt_card_id}, socket) do
138-
game = socket.assigns.game
139141
player = socket.assigns.player
140-
141-
# Validate game lifecycle - voting only allowed during active games
142-
unless Copi.Cornucopia.Game.game_active?(game) do
143-
Logger.warning("Voting attempt on inactive game: player_id: #{player.id}, game_id: #{game.id}, started_at: #{game.started_at}, finished_at: #{game.finished_at}")
144-
{:noreply, socket}
145-
else
146-
{:ok, dealt_card} = DealtCard.find(dealt_card_id)
147-
148-
# Validate that dealt card belongs to current game
149-
unless dealt_card_belongs_to_game?(dealt_card, game) do
150-
Logger.warning("Unauthorized voting attempt: player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}")
142+
game_id = socket.assigns.player.game_id
143+
144+
# Load fresh game record from DB to avoid stale socket assigns
145+
with {:ok, game} <- Copi.Cornucopia.Game.find(game_id) do
146+
# Validate game lifecycle - voting only allowed during active games
147+
unless Copi.Cornucopia.Game.game_active?(game) do
148+
Logger.warning("Voting attempt on inactive game: player_id: #{player.id}, game_id: #{game.id}, started_at: #{game.started_at}, finished_at: #{game.finished_at}")
151149
{:noreply, socket}
152150
else
153-
vote = get_vote(dealt_card, player)
154-
155-
if vote do
156-
Logger.debug("Player has voted: player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}")
157-
Copi.Repo.delete!(vote)
151+
{:ok, dealt_card} = DealtCard.find(dealt_card_id)
152+
153+
# Validate that dealt card belongs to current game
154+
unless dealt_card_belongs_to_game?(dealt_card, game) do
155+
Logger.warning("Unauthorized voting attempt: player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}")
156+
{:noreply, socket}
158157
else
159-
Logger.debug("Player has not voted: player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}")
160-
case Copi.Repo.insert(%Copi.Cornucopia.Vote{dealt_card_id: String.to_integer(dealt_card_id), player_id: player.id}) do
161-
{:ok, _vote} ->
162-
Logger.debug("Vote added successfully for player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}")
163-
{:error, changeset} ->
164-
Logger.warning("Voting failed for player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}, errors: #{inspect(changeset.errors)}")
158+
vote = get_vote(dealt_card, player)
159+
160+
if vote do
161+
Logger.debug("Player has voted: player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}")
162+
Copi.Repo.delete!(vote)
163+
else
164+
Logger.debug("Player has not voted: player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}")
165+
case Copi.Repo.insert(%Copi.Cornucopia.Vote{dealt_card_id: String.to_integer(dealt_card_id), player_id: player.id}) do
166+
{:ok, _vote} ->
167+
Logger.debug("Vote added successfully for player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}")
168+
{:error, changeset} ->
169+
Logger.warning("Voting failed for player_id: #{player.id}, dealt_card_id: #{dealt_card_id}, game_id: #{game.id}, errors: #{inspect(changeset.errors)}")
170+
end
165171
end
166-
end
167172

168-
{:ok, updated_game} = Game.find(game.id)
173+
# Reload fresh game record after vote mutations
174+
{:ok, updated_game} = Copi.Cornucopia.Game.find(game_id)
169175

170-
CopiWeb.Endpoint.broadcast(topic(updated_game.id), "game:updated", updated_game)
176+
CopiWeb.Endpoint.broadcast(topic(updated_game.id), "game:updated", updated_game)
171177

172-
{:noreply, assign(socket, :game, updated_game)}
178+
{:noreply, assign(socket, :game, updated_game)}
179+
end
173180
end
181+
else
182+
{:error, _reason} -> {:noreply, socket}
174183
end
175184
end
176185

0 commit comments

Comments
 (0)