Add anonymous feedback sessions and vote support - #26
Conversation
- Add anonymous session utility (server/utils/anonymous-session.ts) that manages HttpOnly cookie-based sessions with 90-day expiry - Update feedback POST routes (internal + public) to associate anonymous sessions with feedback submissions via authorSessionId - Update vote POST route to allow anonymous voting (was auth-only) - Update feedback GET routes to track hasVoted and isOwn for anonymous users - Add session merge API (POST /api/auth/merge-anonymous) that transfers feedback and votes to authenticated user on login, handling duplicates - Update public feedback page to highlight own submissions with ring style and "Your submission" badge, enable anonymous voting, add email helper text - Add Playwright e2e tests for anonymous feedback flows https://claude.ai/code/session_01Wxa3T56cAhuTFJDx2qUrpQ
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1d614fe53a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const voteCondition = userId | ||
| ? and(eq(vote.feedbackId, id), eq(vote.voterUserId, userId)) | ||
| : and(eq(vote.feedbackId, id), eq(vote.voterSessionId, anonSessionId!)) |
There was a problem hiding this comment.
Check session vote when authenticated before inserting vote
When session.user is present, voteCondition only looks at voterUserId, so an existing anonymous vote from the same browser (voterSessionId) is ignored. If a person votes anonymously and then authenticates before the merge step runs, this branch inserts a second vote row and increments feedback.voteCount again, allowing the same person to be counted twice for one feedback item.
Useful? React with 👍 / 👎.
|
|
||
| export default defineEventHandler(async (event) => { | ||
| const session = await requireAuth(event) | ||
| const session = await optionalAuth(event) |
There was a problem hiding this comment.
Gate anonymous voting to public feedback items
This handler now uses optionalAuth, but it never checks whether the target feedback belongs to a public project before accepting an unauthenticated vote. As a result, any unauthenticated request with a known feedback ID from a private project can still mutate vote counts, which violates private-project access expectations.
Useful? React with 👍 / 👎.
Summary
This PR implements anonymous feedback submission and voting for unauthenticated users. Anonymous sessions are managed via HttpOnly cookies and can be merged into user accounts upon authentication.
Key Changes
Anonymous Session Management
server/utils/anonymous-session.tsto handle session lifecycle:anonymous_sessiontable with 90-day TTLveerify_anon_session) persists across browser restartsFeedback & Voting APIs
Vote endpoint (
/api/feedback/[id]/vote.post.ts):requireAuthtooptionalAuthto allow anonymous votingvoterSessionIdfor anonymous users,voterUserIdfor authenticated usersFeedback submission (
/api/feedback/index.post.tsand public variant):authorSessionIdfield to track anonymous submissionsFeedback listing (
/api/feedback/index.get.tsand public variant):hasVotedstatus for both authenticated and anonymous usersisOwnflag to identify user's own submissionsSession Merge on Authentication
/api/auth/merge-anonymous.post.ts:UI Enhancements
ring-2 ring-primary/30) for own submissionsTesting
tests/e2e/anonymous-feedback.spec.ts):Implementation Details
https://claude.ai/code/session_01Wxa3T56cAhuTFJDx2qUrpQ