Fix Auth.js session callback & jwt update() so avatar/name/email alwa…#391
Conversation
|
@okeolaolatun23-glitch Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Contributor
|
Please resolve the CI failures |
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.
Closes #345
Summary
Two bugs in
lib/auth-config.ts(and one incomponents/avatar-upload.tsx) combined to make avatar updates a silent no-op: thesessioncallback replacedsession.userentirely instead of spreading it, and thejwtcallback never handledtrigger === "update", soupdateSession()calls from the client were completely ignored. This PR fixes both callbacks and the upload component so that profile changes (avatar, name, email) reflect immediately in alluseSession()consumers without requiring a full page reload.Files modified
Root cause analysis
1.
sessioncallback replacedsession.userinstead of spreading itBefore
session.user.name,.email, and.imagewere discarded, so any component reading those fields (nav avatar, display name, etc.) receivedundefined.After
2.
jwtcallback ignoredtrigger === "update"Before
Auth.js calls the
jwtcallback withtrigger: "update"and asessionargument wheneverupdateSession()is called client-side. Because the callback never inspected those parameters, every update was silently discarded.After
Only fields that are explicitly present in the update payload are merged, so a partial update (e.g. only
image) does not accidentally wipenameoremail.3.
avatar-upload.tsxsent the wrong payload shapeBefore
Spreading
session.userhere inlined custom fields (id,walletAddress, …) at theuserlevel, which did match the expected shape. However because thejwtcallback didn't read them at all, the result was still a no-op.After
Only the changed field is sent. The
jwtcallback'strigger === "update"branch selectively merges it into the token, and thesessioncallback mapstoken.picture→session.user.image. All consumers update without a reload.Auth.js callback data flow (corrected)
TypeScript module augmentation
The PR also adds explicit
declare module "next-auth"anddeclare module "next-auth/jwt"blocks so thatsession.user.walletAddress,session.user.username,token.walletAddress, andtoken.usernameare all typed — eliminating the(session.user as any)casts that previously masked the bug.Testing checklist
userobject provided →token.id,token.walletAddress,token.username,token.pictureare all set.trigger === "update"withsession.user.image→token.pictureupdated; other token fields unchanged.session.user.name,.email,.imageare present in the returned session alongsideid,walletAddress,username.useSession().data.user.imagereflects the new URL in the same browser session withoutwindow.location.reload().updateSession(), the nav bar avatar src updates without a full reload.id,walletAddress,usernameon the session.updateSession({ user: { image } })does not nullifynameoremail.References
- Auth.js docs — Callbacks
- Auth.js docs — Session update /
- Issue Auth.js session callback overwrites session.user and the jwt callback ignores update() — avatar/name/email never reflect #345 — Auth.js session callback overwrites session.user and jwt callback ignores update()
# PR #345 — Fix Auth.js session callback & jwt `update()` so avatar/name/email always reflecttrigger: "update"Summary
Two bugs in
lib/auth-config.ts(and one incomponents/avatar-upload.tsx) combined to make avatar updates a silent no-op: thesessioncallback replacedsession.userentirely instead of spreading it, and thejwtcallback never handledtrigger === "update", soupdateSession()calls from the client were completely ignored. This PR fixes both callbacks and the upload component so that profile changes (avatar, name, email) reflect immediately in alluseSession()consumers without requiring a full page reload.Files modified
app/lib/auth-config.tsjwtandsessioncallbacksapp/components/avatar-upload.tsxupdateSession()call shapeRoot cause analysis
1.
sessioncallback replacedsession.userinstead of spreading itBefore
session.user.name,.email, and.imagewere discarded, so any component reading those fields (nav avatar, display name, etc.) receivedundefined.After
2.
jwtcallback ignoredtrigger === "update"Before
Auth.js calls the
jwtcallback withtrigger: "update"and asessionargument wheneverupdateSession()is called client-side. Because the callback never inspected those parameters, every update was silently discarded.After
Only fields that are explicitly present in the update payload are merged, so a partial update (e.g. only
image) does not accidentally wipenameoremail.3.
avatar-upload.tsxsent the wrong payload shapeBefore
Spreading
session.userhere inlined custom fields (id,walletAddress, …) at theuserlevel, which did match the expected shape. However because thejwtcallback didn't read them at all, the result was still a no-op.After
Only the changed field is sent. The
jwtcallback'strigger === "update"branch selectively merges it into the token, and thesessioncallback mapstoken.picture→session.user.image. All consumers update without a reload.Auth.js callback data flow (corrected)
TypeScript module augmentation
The PR also adds explicit
declare module "next-auth"anddeclare module "next-auth/jwt"blocks so thatsession.user.walletAddress,session.user.username,token.walletAddress, andtoken.usernameare all typed — eliminating the(session.user as any)casts that previously masked the bug.Testing checklist
userobject provided →token.id,token.walletAddress,token.username,token.pictureare all set.trigger === "update"withsession.user.image→token.pictureupdated; other token fields unchanged.session.user.name,.email,.imageare present in the returned session alongsideid,walletAddress,username.useSession().data.user.imagereflects the new URL in the same browser session withoutwindow.location.reload().updateSession(), the nav bar avatar src updates without a full reload.id,walletAddress,usernameon the session.updateSession({ user: { image } })does not nullifynameoremail.