Skip to content

Commit 32560e9

Browse files
authored
fix: trigger login hooks after reset password (#14711)
### What? Added execution of `beforeLogin` and `afterLogin` hooks during the password reset operation in `resetPasswordOperation()`. These hooks now execute with the same parameters and flow as they do in the standard login operation, ensuring consistent behavior across both authentication paths. - `packages/payload/src/auth/operations/resetPassword.ts` - Added hook execution before and after JWT token generation. ### Why? When a user resets their password, the operation performs two phases: updating the password in the database, then automatically logging the user in with a new session and JWT token. However, `beforeLogin` and `afterLogin` hooks were not being triggered during this auto-login phase, creating inconsistent behavior compared to standard login. This caused issues for applications that uses `afterLogin` hooks to attach additional cookie (for example). ### How? Triggered `beforeLogin` and `afterLogin` in `resetPassword.ts`
1 parent a044a08 commit 32560e9

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

packages/payload/src/auth/operations/resetPassword.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,49 @@ export const resetPasswordOperation = async <TSlug extends CollectionSlug>(
163163

164164
const fieldsToSign = getFieldsToSign(fieldsToSignArgs)
165165

166+
// /////////////////////////////////////
167+
// beforeLogin - Collection
168+
// /////////////////////////////////////
169+
170+
let userBeforeLogin = user
171+
172+
if (collectionConfig.hooks?.beforeLogin?.length) {
173+
for (const hook of collectionConfig.hooks.beforeLogin) {
174+
userBeforeLogin =
175+
(await hook({
176+
collection: args.collection?.config,
177+
context: args.req.context,
178+
req: args.req,
179+
user: userBeforeLogin,
180+
})) || userBeforeLogin
181+
}
182+
}
183+
166184
const { token } = await jwtSign({
167185
fieldsToSign,
168186
secret,
169187
tokenExpiration: collectionConfig.auth.tokenExpiration,
170188
})
171189

190+
req.user = userBeforeLogin
191+
192+
// /////////////////////////////////////
193+
// afterLogin - Collection
194+
// /////////////////////////////////////
195+
196+
if (collectionConfig.hooks?.afterLogin?.length) {
197+
for (const hook of collectionConfig.hooks.afterLogin) {
198+
userBeforeLogin =
199+
(await hook({
200+
collection: args.collection?.config,
201+
context: args.req.context,
202+
req: args.req,
203+
token,
204+
user: userBeforeLogin,
205+
})) || userBeforeLogin
206+
}
207+
}
208+
172209
const fullUser = await payload.findByID({
173210
id: user.id,
174211
collection: collectionConfig.slug,

test/hooks/int.spec.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,47 @@ describe('Hooks', () => {
411411
expect(result.afterLoginHook).toStrictEqual(true)
412412
})
413413

414+
it('should call afterLogin hook on password reset', async () => {
415+
const resetUser = await payload.create({
416+
collection: hooksUsersSlug,
417+
data: {
418+
email: 'reset-test@payloadcms.com',
419+
password: devUser.password,
420+
roles: ['admin'],
421+
afterLoginHook: false,
422+
},
423+
})
424+
425+
expect(resetUser.afterLoginHook).toStrictEqual(false)
426+
427+
const token = await payload.forgotPassword({
428+
collection: hooksUsersSlug,
429+
data: {
430+
email: resetUser.email,
431+
},
432+
disableEmail: true,
433+
})
434+
435+
const { user } = await payload.resetPassword({
436+
collection: hooksUsersSlug,
437+
overrideAccess: true,
438+
data: {
439+
password: 'newPassword123',
440+
token,
441+
},
442+
})
443+
444+
expect(user).toBeDefined()
445+
expect(user.afterLoginHook).toStrictEqual(true)
446+
447+
const result = await payload.findByID({
448+
id: user.id,
449+
collection: hooksUsersSlug,
450+
})
451+
452+
expect(result.afterLoginHook).toStrictEqual(true)
453+
})
454+
414455
it('deny user login', async () => {
415456
await expect(() =>
416457
payload.login({

0 commit comments

Comments
 (0)