Repository navigation
fix(events): match mine:true by auth.id instead of empty-string username fallback - #60
Open
detail-app[bot] wants to merge 1 commit into
Conversation
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.
Detail bug report: View on Detail
Bug
EventsWhereInput.toQuery(auth)(consumed by theeventsquery) built themine: trueclause by readingauth.username || ''for the mentor, manager, and student branches. But every mentor/student token ever issued by this repo is ID-target (tgt: AuthByTarget.ID, sid: <user-id>viasignTokenUser), for whichAuthContext.usernameisundefinedandAuthContext.idholds the user id. So for every real caller the predicate emittedusername: ""/managerUsername: "", which:mine: truereturned empty for the logged-in mentor/student.Mentor/Studentrow whoseusername = ""(which any mentor/student can self-clear viaeditMentor/editStudent's falsy guards) → cross-user misattribution of events.EventsWhereInputwas the only call site readingauth.usernamedirectly instead of dispatching viaidOrUsernameOrAuthToUniqueWhere.Fix
In
src/inputs/EventsWhereInput.ts, themineclause now matches byauth.idandauth.usernamewith no|| ''fallback, and themanagerUsernamebranch is only emitted whenauth.usernameis defined:For the issued ID-target tokens this reduces to
{ mentors/students: { some: { id: auth.id } } }(Prisma stripsundefinedkeys), matching only the caller's own rows and nousername = ""row. ThemanagerUsernamebranch is guarded because leaving a baremanagerUsername: undefinedcollapses to{mentors:{some:{}}}= "any event with a mentor", which I confirmed empirically would leak events; guarding it onauth.usernamekeeps it for the designed-for username-target manager path while closing that leak for ID-target and unauthenticated callers.Testing
tests/testEventsWhereInput.ts, a DB-less suite (repo'snode:test+node:assert/strictconventions) asserting thetoQuery()predicate shape across five callers: ID-target mentor and student (via the realsignTokenUser), username-target mentor and manager (hand-minted JWTs exercising the designed-for branch), and an unauthenticated caller. It verifies themineOR emitsidfor ID-target tokens, omits the manager branch whenauth.usernameis undefined, and never contains ausername:""/managerUsername:""fallback. Also coversmineunset and composition withpublic/partnerCode.tests/testSlackReporting.tsall pass; the production diff is limited tosrc/inputs/EventsWhereInput.ts(3 lines) plus the new test, so the other resolvers that dispatch viaidOrUsernameOrAuthToUniqueWhereare untouched and unaffected.postgres:15-alpine, schema applied viaprisma db pushbecauseprisma migrate deployfails on a fresh DB due to a pre-existing repo migration-history inconsistency —20220610164033_add_event_id_to_student_mentor_projectdrops an index no earlier migration creates). Seeded events with an ID-target mentor, an ID-target student, and ausername:""mentor (the misattribution seed), then queried through the repo's realPrismaClient+EventsWhereInput.toQuery()+signTokenUser: the ID-target mentor received only their own event (not theusername:""row's event), a different ID-target mentor did not receive theusername:""row's event (no cross-user misattribution), and an unauthenticatedmine: truecall returned[]. This DB-backed test was not versioned since it requires a live database the repo's CI (docker buildonly) does not provision.npx eslint) hits a pre-existing environmental failure:@typescript-eslint/parser(via the pinned@codeday/eslint-typescript-configon eslint 7) is incompatible with the installed TypeScript 5.2.2 and errors withDeprecationError: 'originalKeywordKind'before any rule runs. The identical error reproduces on the untouchedtests/testSlackReporting.ts, so it is not introduced by this change; CI does not run lint. Resolving it is a separate tooling-upgrade task.Automatic Fixes PRs can be configured here.