Repository navigation
fix(web): read the Didit callback status from the provider, not the client - #1068
rudrasatani13 wants to merge 1 commit into
Conversation
Plan expiredYour subscription has expired. Please renew your subscription to continue using CI/CD integration and other features. |
|
@rudrasatani13 is attempting to deploy a commit to the kindfi Team on Vercel. A member of the Team first needs to authorize it. |
|
Warning Review limit reachedNext included review available in 30 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
|
Closes #1022
Two browser-facing paths persisted a KYC status the browser chose.
The callback route accepted
{ verificationSessionId, status }and storedstatusdirectly. Worse,app/(routes)/profile/page.tsxreadsearchParams.statusand stored that — so/profile?kyc=completed&verificationSessionId=<any own session>&status=Approvedwas enough to mark a user approved. BecauseapplyDiditStatusUpdatecallsactivatePollarIfApproved, that also reached wallet activation, which is the "self-approval and unintended Pollar wallet activation" the issue names.The change
One shared path,
lib/kyc/refresh-session-status.ts, now used by both entry points:findDiditSessionBySessionId, thenrecord.userId === userId. A session that belongs to someone else is reported exactly like one that does not exist — both are403 Unknown verification session— so neither route can be used to probe for session ids.getDiditSessionStatusis the only source; no request field reachesapplyDiditStatusUpdate.202withreason: 'provider_unavailable'; the webhook andcheck-statusremain the trusted paths and will apply the real status when Didit is reachable again.The request body is now
{ verificationSessionId }only, the route's validator rejects anything without it and ignoresstatusentirely, and both profile dashboards stop sending it. The two dashboards also stopped showing a status toast derived from the query string — it was cosmetic, but it was the same browser-supplied value presented as a result.Acceptance criteria
403; test "writes nothing for a session that belongs to another user"statusremoved from the body type, the validator, both clients, and the profile pagegetDiditSessionStatusis the only writer input; provider failure writes nothingapplyDiditStatusUpdatewith a client value, soactivatePollarIfApprovedcan only be reached on a provider-reported approvalVerification
The five cases are: applies what Didit reports; another user's session writes nothing; unknown session writes nothing; provider unreachable writes nothing; and a declined session is stored as declined rather than as whatever the caller wanted.
Notes
profile-dashboard-v2.tsx(unuseduseRouterimport, unused parameter) — they are in the repository's existing lint output, not introduced here, and I left them rather than mixing a cleanup into a security fix.req.iptype error inside thewithRateLimitidentifier, unchanged by this PR.