@@ -358,10 +358,15 @@ export class NextAppAuth extends NextAuth {
358
358
[ "email" ] ,
359
359
"email missing from request body"
360
360
) ;
361
- ( await this . core ) . sendPasswordResetEmail (
362
- email ,
363
- this . options . passwordResetUrl
364
- ) ;
361
+ const { verifier } = await (
362
+ await this . core
363
+ ) . sendPasswordResetEmail ( email , this . options . passwordResetUrl ) ;
364
+ cookies ( ) . set ( {
365
+ name : this . options . pkceVerifierCookieName ,
366
+ value : verifier ,
367
+ httpOnly : true ,
368
+ sameSite : "strict" ,
369
+ } ) ;
365
370
return new Response ( null , { status : 204 } ) ;
366
371
}
367
372
case "emailpassword/reset-password" : {
@@ -372,6 +377,14 @@ export class NextAppAuth extends NextAuth {
372
377
}
373
378
let tokenData : TokenData ;
374
379
try {
380
+ const verifier = req . cookies . get (
381
+ this . options . pkceVerifierCookieName
382
+ ) ?. value ;
383
+ if ( ! verifier ) {
384
+ return onEmailPasswordReset ( {
385
+ error : new Error ( "no pkce verifier cookie found" ) ,
386
+ } ) ;
387
+ }
375
388
const [ resetToken , password ] = _extractParams (
376
389
await _getReqBody ( req ) ,
377
390
[ "reset_token" , "password" ] ,
@@ -380,7 +393,7 @@ export class NextAppAuth extends NextAuth {
380
393
381
394
tokenData = await (
382
395
await this . core
383
- ) . resetPasswordWithResetToken ( resetToken , password ) ;
396
+ ) . resetPasswordWithResetToken ( resetToken , verifier , password ) ;
384
397
} catch ( err ) {
385
398
return onEmailPasswordReset ( {
386
399
error : err instanceof Error ? err : new Error ( String ( err ) ) ,
@@ -392,6 +405,7 @@ export class NextAppAuth extends NextAuth {
392
405
httpOnly : true ,
393
406
sameSite : "strict" ,
394
407
} ) ;
408
+ cookies ( ) . delete ( this . options . pkceVerifierCookieName ) ;
395
409
return onEmailPasswordReset ( { error : null , tokenData } ) ;
396
410
}
397
411
case "emailpassword/resend-verification-email" : {
@@ -476,30 +490,43 @@ export class NextAppAuth extends NextAuth {
476
490
throw new Error ( `'passwordResetUrl' option not configured` ) ;
477
491
}
478
492
const [ email ] = _extractParams ( data , [ "email" ] , "email missing" ) ;
479
- await (
493
+ const { verifier } = await (
480
494
await this . core
481
495
) . sendPasswordResetEmail (
482
496
email ,
483
497
`${ this . options . baseUrl } /${ this . options . passwordResetUrl } `
484
498
) ;
499
+ cookies ( ) . set ( {
500
+ name : this . options . pkceVerifierCookieName ,
501
+ value : verifier ,
502
+ httpOnly : true ,
503
+ sameSite : "strict" ,
504
+ } ) ;
485
505
} ,
486
506
emailPasswordResetPassword : async (
487
507
data : FormData | { resetToken : string ; password : string }
488
508
) => {
509
+ const verifier = cookies ( ) . get (
510
+ this . options . pkceVerifierCookieName
511
+ ) ?. value ;
512
+ if ( ! verifier ) {
513
+ throw new Error ( "no pkce verifier cookie found" ) ;
514
+ }
489
515
const [ resetToken , password ] = _extractParams (
490
516
data ,
491
517
[ "reset_token" , "password" ] ,
492
518
"reset_token or password missing"
493
519
) ;
494
520
const tokenData = await (
495
521
await this . core
496
- ) . resetPasswordWithResetToken ( resetToken , password ) ;
522
+ ) . resetPasswordWithResetToken ( resetToken , verifier , password ) ;
497
523
cookies ( ) . set ( {
498
524
name : this . options . authCookieName ,
499
525
value : tokenData . auth_token ,
500
526
httpOnly : true ,
501
527
sameSite : "strict" ,
502
528
} ) ;
529
+ cookies ( ) . delete ( this . options . pkceVerifierCookieName ) ;
503
530
return tokenData ;
504
531
} ,
505
532
emailPasswordResendVerificationEmail : async (
0 commit comments