Implement a way for players to resume game state if they get thrown out of the game due to client-side JS issues.#3228
Open
sydseter wants to merge 10 commits into
Open
Implement a way for players to resume game state if they get thrown out of the game due to client-side JS issues.#3228sydseter wants to merge 10 commits into
sydseter wants to merge 10 commits into
Conversation
…ed in case their frontend state gets stale
…ed in case their frontend state gets stale
Contributor
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a “resume player session” mechanism to Copi to reduce the chance that players get stranded on the game page when their player state becomes unusable. It persists a small (encrypted) session pointer from the player page, and the game page can then render a resume link back to the player URL; frontend test tooling/coverage is also introduced for the assets bundle.
Changes:
- Add a session-backed resume pointer API (
PUT /api/games/:game_id/players/:player_id/session,DELETE /api/games/:game_id/player-session) protected by browser session + CSRF. - Render a “Resume player session” call-to-action on the game page when a valid resume pointer exists for that game; add a LiveView hook on the player page to persist/clear the pointer.
- Introduce Vitest-based frontend tests + coverage reporting, plus CI wiring and
mix assets.coverage/mix assets.testaliases.
Reviewed changes
Copilot reviewed 24 out of 26 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| copi.owasp.org/test/copi_web/live/game_live/show_test.exs | Adds LiveView test covering resume-link rendering based on session pointer. |
| copi.owasp.org/test/copi_web/controllers/api_controller_test.exs | Adds controller tests for persisting/clearing the resume pointer and validation cases. |
| copi.owasp.org/SECURITY.md | Expands security/threat-model documentation with additional known integrity and transport concerns. |
| copi.owasp.org/README.md | Documents the new mix assets.coverage command. |
| copi.owasp.org/mix.exs | Adds Mix aliases for running asset tests and coverage via npm. |
| copi.owasp.org/lib/copi_web/router.ex | Introduces :browser_api pipeline and routes for the session pointer endpoints. |
| copi.owasp.org/lib/copi_web/live/player_live/show.html.heex | Adds PersistPlayerSession hook element and fixes button type usage; aligns assigns to @game. |
| copi.owasp.org/lib/copi_web/live/player_live/form_component.ex | Ensures join button explicitly submits (type="submit"). |
| copi.owasp.org/lib/copi_web/live/game_live/show.html.heex | Adds resume banner/link to the game page UI. |
| copi.owasp.org/lib/copi_web/live/game_live/show.ex | Reads resume pointer from session and assigns :resume_player_id for rendering. |
| copi.owasp.org/lib/copi_web/live/game_live/create_game_form.ex | Ensures create-game button explicitly submits (type="submit"). |
| copi.owasp.org/lib/copi_web/endpoint.ex | Enables encrypted session cookies and hardens cookie flags (HttpOnly, Secure in prod). |
| copi.owasp.org/lib/copi_web/controllers/api_controller.ex | Adds persist/clear session pointer actions with ULID validation + cache-control hardening. |
| copi.owasp.org/lib/copi_web/components/core_components/buttons.ex | Defaults button components to type="button" to avoid unintended form submits. |
| copi.owasp.org/lib/copi_web/components/core_components.ex | Updates example usage to explicitly submit (type="submit"). |
| copi.owasp.org/assets/vitest.config.mts | Adds Vitest configuration including coverage thresholds and module stubs. |
| copi.owasp.org/assets/test/stubs/phoenix.ts | Adds Phoenix Socket stub for unit tests. |
| copi.owasp.org/assets/test/stubs/phoenix_live_view.ts | Adds LiveSocket stub for unit tests. |
| copi.owasp.org/assets/test/stubs/phoenix_html.ts | Adds phoenix_html stub for unit tests. |
| copi.owasp.org/assets/test/globals.d.ts | Declares minimal global typings for the test environment. |
| copi.owasp.org/assets/test/appHarness.ts | Provides a test harness that mocks dependencies and imports app.js in isolation. |
| copi.owasp.org/assets/test/app.test.ts | Adds extensive unit tests for app.js hooks/behavior including session pointer sync. |
| copi.owasp.org/assets/package.json | Adds Vitest/Vite/jsdom + coverage tooling and scripts. |
| copi.owasp.org/assets/package-lock.json | Updates lockfile to include the new dev dependencies. |
| copi.owasp.org/assets/js/app.js | Implements PersistPlayerSession hook + ULID validation and session endpoint calls. |
| .github/workflows/copi-build.yml | Adds Node setup and runs frontend coverage in CI. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
We still have issues with players getting thrown out of their session due to corrupt player state. These changes are added to mitigate this issue.
I have added a resume player session flow. The player page writes a small server-side session pointer so the game page can offer a resume link back to that player URL. The game page reads the player's cookie depending on whether the CSRF cookie is valid or not and renders the resume link.
This should mitigate the earlier problem where a player could end up back on the game page and be effectively stranded because joining is blocked after the game has started. The DELETE /player-session route exists specifically to clear that resume pointer when it should no longer be retained. That happens when the player view has data-store-player-session set to false.
The delete is scoped by game_id, not by player_id. The player page sets data-store-player-session to false when the game is finished, and the hook then sends DELETE. The controller only checks whether the stored session pointer has the same game_id before deleting it.
The frontend test coverage has been increased to 98% for Copi.
AI Tool Disclosure
GitHub CoPilotGPT-5.4Create TypeScript unit tests and integration tests for the frontend code of copi.owasp.org/. Do not change production code. Make sure the code coverage is 95%. Mock the Elixir api endpoints and ensure the tests run for every pull request against master. Some players often experience, after having played their card, being redirected to the game overview after clicking the "next round" button. They are then unable to continue their session and are informed that they can not get into the game as it has already started. The issues could be related to having multiple instances of the elixir app, but there are no sessions here, so it appears that it could also be a frontend issue where the player state is no longer valid and that the player therefore gets "thrown out" after clicking "next round". Please investigate why this happens and implement mitigations that may help the players keep their state and avoid having them get redirected to the game overview page. I don't want the state of the player to survive closing the browser. Would it be possible to ensure the player state is destroyed when closing the browser? Please take all security precautions necessary according to OWASP best practices to ensure there is no chance of information disclosure. You are an application security engineer. Please audit this code from a security perspective. Authentication is not supported. Besides that, are there any concerns I should be aware of?Affirmation