File tree Expand file tree Collapse file tree 4 files changed +77
-2
lines changed
packages/payload/src/auth/operations Expand file tree Collapse file tree 4 files changed +77
-2
lines changed Original file line number Diff line number Diff line change @@ -137,8 +137,8 @@ export const forgotPasswordOperation = async <TSlug extends CollectionSlug>(
137
137
138
138
user . resetPasswordToken = token
139
139
user . resetPasswordExpiration = new Date (
140
- collectionConfig . auth ?. forgotPassword ?. expiration || expiration || Date . now ( ) + 3600000 ,
141
- ) . toISOString ( ) // 1 hour
140
+ Date . now ( ) + ( collectionConfig . auth ?. forgotPassword ?. expiration ?? expiration ?? 3600000 ) ,
141
+ ) . toISOString ( )
142
142
143
143
user = await payload . update ( {
144
144
id : user . id ,
Original file line number Diff line number Diff line change @@ -605,6 +605,43 @@ describe('Access Control', () => {
605
605
expect ( res ) . toBeTruthy ( )
606
606
} )
607
607
} )
608
+
609
+ describe ( 'Auth - Local API' , ( ) => {
610
+ it ( 'should not allow reset password if forgotPassword expiration token is expired' , async ( ) => {
611
+ // Mock Date.now() to simulate the forgotPassword call happening 1 hour ago (default is 1 hour)
612
+ const originalDateNow = Date . now
613
+ const mockDateNow = jest . spyOn ( Date , 'now' ) . mockImplementation ( ( ) => {
614
+ // Move the current time back by 1 hour
615
+ return originalDateNow ( ) - 60 * 60 * 1000
616
+ } )
617
+
618
+ let forgot
619
+ try {
620
+ // Call forgotPassword while the mocked Date.now() is active
621
+ forgot = await payload . forgotPassword ( {
622
+ collection : 'users' ,
623
+ data : {
624
+ email : 'dev@payloadcms.com' ,
625
+ } ,
626
+ } )
627
+ } finally {
628
+ // Restore the original Date.now() after the forgotPassword call
629
+ mockDateNow . mockRestore ( )
630
+ }
631
+
632
+ // Attempt to reset password, which should fail because the token is expired
633
+ await expect (
634
+ payload . resetPassword ( {
635
+ collection : 'users' ,
636
+ data : {
637
+ password : 'test' ,
638
+ token : forgot ,
639
+ } ,
640
+ overrideAccess : true ,
641
+ } ) ,
642
+ ) . rejects . toThrow ( 'Token is either invalid or has expired.' )
643
+ } )
644
+ } )
608
645
} )
609
646
610
647
async function createDoc < TSlug extends CollectionSlug = 'posts' > (
Original file line number Diff line number Diff line change @@ -44,6 +44,9 @@ export default buildConfigWithDefaults({
44
44
tokenExpiration : 7200 , // 2 hours
45
45
useAPIKey : true ,
46
46
verify : false ,
47
+ forgotPassword : {
48
+ expiration : 300000 , // 5 minutes
49
+ } ,
47
50
} ,
48
51
fields : [
49
52
{
Original file line number Diff line number Diff line change @@ -932,5 +932,40 @@ describe('Auth', () => {
932
932
933
933
expect ( reset . user . email ) . toStrictEqual ( 'dev@payloadcms.com' )
934
934
} )
935
+
936
+ it ( 'should not allow reset password if forgotPassword expiration token is expired' , async ( ) => {
937
+ // Mock Date.now() to simulate the forgotPassword call happening 6 minutes ago (current expiration is set to 5 minutes)
938
+ const originalDateNow = Date . now
939
+ const mockDateNow = jest . spyOn ( Date , 'now' ) . mockImplementation ( ( ) => {
940
+ // Move the current time back by 6 minutes (360,000 ms)
941
+ return originalDateNow ( ) - 6 * 60 * 1000
942
+ } )
943
+
944
+ let forgot
945
+ try {
946
+ // Call forgotPassword while the mocked Date.now() is active
947
+ forgot = await payload . forgotPassword ( {
948
+ collection : 'users' ,
949
+ data : {
950
+ email : 'dev@payloadcms.com' ,
951
+ } ,
952
+ } )
953
+ } finally {
954
+ // Restore the original Date.now() after the forgotPassword call
955
+ mockDateNow . mockRestore ( )
956
+ }
957
+
958
+ // Attempt to reset password, which should fail because the token is expired
959
+ await expect (
960
+ payload . resetPassword ( {
961
+ collection : 'users' ,
962
+ data : {
963
+ password : 'test' ,
964
+ token : forgot ,
965
+ } ,
966
+ overrideAccess : true ,
967
+ } ) ,
968
+ ) . rejects . toThrow ( 'Token is either invalid or has expired.' )
969
+ } )
935
970
} )
936
971
} )
You can’t perform that action at this time.
0 commit comments