Feature: Add Google OAuth for Leaderboard Name Claiming#2
Conversation
- Installed `@convex-dev/auth` and `@auth/core`. - Configured Convex Google OAuth and user tables. - Added a `UserMenu` to login/logout using Google. - Implemented `claimName` endpoint to claim custom display names and associate past anonymous scores with the user's account. - Prevent anonymous users from submitting scores with claimed names. Co-authored-by: threehymns <70611435+threehymns@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Found 4 issues to address before merging:
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
| import SettingsPage from './components/SettingsPage'; | ||
| import GameModeScreen from './components/GameModeScreen'; | ||
| import Leaderboard from './components/Leaderboard'; | ||
| import { UserMenu } from './components/UserMenu'; |
There was a problem hiding this comment.
UserMenu is imported here but never rendered in the component's JSX. The sign-in/sign-out UI won't be visible to users, which defeats the purpose of this PR. You likely need to add <UserMenu /> somewhere in the returned markup (e.g. alongside the other top-level UI elements).
Fix it with Roo Code or mention @roomote and request a fix.
| localStorage.setItem('matchfield-player-name', trimmedName); | ||
|
|
||
| // If user is logged in but hasn't claimed a name or is changing it | ||
| if (userName !== undefined && userName !== null && userName !== trimmedName) { |
There was a problem hiding this comment.
This condition skips claimName when userName === null, which is the state for a logged-in user who hasn't claimed a name yet. On their first score submission the name is never claimed, so it remains unprotected and another user could later claim it. The condition should also handle the userName === null case, e.g.:
| if (userName !== undefined && userName !== null && userName !== trimmedName) { | |
| if (userName !== undefined && userName !== trimmedName) { |
Fix it with Roo Code or mention @roomote and request a fix.
| const allScoresForName = await ctx.db | ||
| .query("leaderboard") | ||
| .filter((q) => q.eq(q.field("playerName"), trimmedName)) | ||
| .collect(); |
There was a problem hiding this comment.
This .filter().collect() does a full table scan of the leaderboard since there's no index on playerName. If the leaderboard grows, this will get increasingly expensive. Consider adding a by_playerName index to the leaderboard table in the schema and using .withIndex() here instead.
Fix it with Roo Code or mention @roomote and request a fix.
| "lucide-react": "^0.552.0", | ||
| "react": "^19.2.0", | ||
| "react-dom": "^19.2.0", | ||
| "resend": "^6.12.2", |
There was a problem hiding this comment.
resend is added as a dependency but is never imported or used anywhere in the codebase. This adds unnecessary weight to node_modules. If it's not needed for a planned email flow, it should be removed.
Fix it with Roo Code or mention @roomote and request a fix.
…to sign in after an anonymous score is recorded. Here is a summary of the changes I've made: - I added a prompt inside `VictoryModal` for anonymous users to sign in with Google immediately after logging a score, allowing them to claim their entered name permanently. - I fixed a bug that caused anonymous users to hit an authentication error when trying to save scores by properly handling `null` user values. - I updated the error display to render a clickable "Sign in with Google" button when a name collision error occurs. - I resolved a backend bug in `claimName` caused by filtering on `undefined` userIds. Co-authored-by: threehymns <70611435+threehymns@users.noreply.github.com>
- Updated the `UserMenu` on the homepage to be a very subtle text link instead of a solid button block per user request. Co-authored-by: threehymns <70611435+threehymns@users.noreply.github.com>
- Fixed a bug where first-time logged-in users couldn't claim a name due to `userName === null` being the only check. Now explicitly uses `isAuthenticated` from `useConvexAuth`. - Optimized the `claimName` migration of anonymous scores by utilizing a new `by_playerName` index in the `leaderboard` table instead of doing a full table scan. - Cleaned up package.json by removing unused `resend` and `@oslojs/crypto` dependencies. Co-authored-by: threehymns <70611435+threehymns@users.noreply.github.com>
- Restored `UserMenu` in `App.tsx` which was accidentally missing. - Refactored `currentUserName` to `currentUserDetails` to return the user's `image` along with their name. - Modified `UserMenu` to display the user's avatar image if it exists, alongside their name, in a small pill, that wraps them inside an anchor tag linking to `/profile`. Co-authored-by: threehymns <70611435+threehymns@users.noreply.github.com>
Added an account system to allow users to sign in with Google using
@convex-dev/auth. Users can now claim a display name when logged in, which retroactively attaches all their old anonymous scores to their account. If a name is already claimed, other anonymous users are prevented from submitting scores with it, ensuring leaderboard integrity.PR created automatically by Jules for task 7346118070983662753 started by @threehymns