1
+ import { mockLogger } from "./lib"
2
+ import type { InternalOptions , LoggerInstance , InternalProvider , CallbacksOptions , Account , Awaitable , Profile , Session , User , CookiesOptions } from "../src"
3
+ import { createPKCE } from "../src/core/lib/oauth/pkce-handler"
4
+ import { InternalUrl } from "../src/utils/parse-url"
5
+ import { JWT , JWTDecodeParams , JWTEncodeParams , JWTOptions } from "../src/jwt"
6
+ import { CredentialInput } from "../src/providers"
7
+
8
+ let logger : LoggerInstance
9
+ let url : InternalUrl
10
+ let provider : InternalProvider < "oauth" >
11
+ let jwt : JWTOptions
12
+ let callbacks : CallbacksOptions
13
+ let cookies : CookiesOptions
14
+ let options : InternalOptions < "oauth" >
15
+
16
+ beforeEach ( ( ) => {
17
+ logger = mockLogger ( )
18
+
19
+ url = {
20
+ origin : "http://localhost:3000" ,
21
+ host : "localhost:3000" ,
22
+ path : "/api/auth" ,
23
+ base : "http://localhost:3000/api/auth" ,
24
+ toString : ( ) => "http://localhost:3000/api/auth"
25
+ }
26
+
27
+ provider = {
28
+ type : "oauth" ,
29
+ id : "testId" ,
30
+ name : "testName" ,
31
+ signinUrl : "/" ,
32
+ callbackUrl : "/" ,
33
+ checks : [ "pkce" , "state" ]
34
+ }
35
+
36
+ jwt = {
37
+ secret : "secret" ,
38
+ maxAge : 0 ,
39
+ encode : function ( params : JWTEncodeParams ) : Awaitable < string > {
40
+ throw new Error ( "Function not implemented." )
41
+ } ,
42
+ decode : function ( params : JWTDecodeParams ) : Awaitable < JWT | null > {
43
+ throw new Error ( "Function not implemented." )
44
+ }
45
+ }
46
+
47
+ callbacks = {
48
+ signIn : function ( params : { user : User ; account : Account ; profile : Profile & Record < string , unknown > ; email : { verificationRequest ?: boolean | undefined } ; credentials ?: Record < string , CredentialInput > | undefined } ) : Awaitable < string | boolean > {
49
+ throw new Error ( "Function not implemented." )
50
+ } ,
51
+ redirect : function ( params : { url : string ; baseUrl : string } ) : Awaitable < string > {
52
+ throw new Error ( "Function not implemented." )
53
+ } ,
54
+ session : function ( params : { session : Session ; user : User ; token : JWT } ) : Awaitable < Session > {
55
+ throw new Error ( "Function not implemented." )
56
+ } ,
57
+ jwt : function ( params : { token : JWT ; user ?: User | undefined ; account ?: Account | undefined ; profile ?: Profile | undefined ; isNewUser ?: boolean | undefined } ) : Awaitable < JWT > {
58
+ throw new Error ( "Function not implemented." )
59
+ }
60
+ }
61
+
62
+ cookies = {
63
+ sessionToken : { name : "" , options : undefined } ,
64
+ callbackUrl : { name : "" , options : undefined } ,
65
+ csrfToken : { name : "" , options : undefined } ,
66
+ pkceCodeVerifier : { name : "" , options : { } } ,
67
+ state : { name : "" , options : undefined } ,
68
+ nonce : { name : "" , options : undefined }
69
+ }
70
+
71
+ options = {
72
+ url,
73
+ action : "session" ,
74
+ provider,
75
+ secret : "" ,
76
+ debug : false ,
77
+ logger,
78
+ session : { strategy : "jwt" , maxAge : 0 , updateAge : 0 } ,
79
+ pages : { } ,
80
+ jwt,
81
+ events : { } ,
82
+ callbacks,
83
+ cookies,
84
+ callbackUrl : '' ,
85
+ providers : [ ] ,
86
+ theme : { }
87
+ }
88
+ } )
89
+
90
+ describe ( "createPKCE" , ( ) => {
91
+ it ( "returns a code challenge, code challenge method, and cookie" , async ( ) => {
92
+ const pkce = await createPKCE ( options )
93
+
94
+ expect ( pkce ?. code_challenge ) . not . toBeNull ( )
95
+ expect ( pkce ?. code_challenge_method ) . toEqual ( "S256" )
96
+ expect ( pkce ?. cookie ) . not . toBeNull ( )
97
+ } )
98
+ it ( "does not return a pkce when the provider does not support pkce" , async ( ) => {
99
+ options . provider . checks = [ "state" ]
100
+
101
+ const pkce = await createPKCE ( options )
102
+
103
+ expect ( pkce ) . toBeUndefined ( )
104
+ } )
105
+ it ( "sets the cookie expiration to a default of 15 minutes when the max age option is not provided" , async ( ) => {
106
+ const pkce = await createPKCE ( options )
107
+
108
+ const defaultMaxAge = 60 * 15 // 15 minutes in seconds
109
+ const expires = new Date ( )
110
+ expires . setTime ( expires . getTime ( ) + defaultMaxAge * 1000 )
111
+
112
+ validateCookieExpiration ( { pkce, expires} )
113
+ expect ( pkce ?. cookie . options . maxAge ) . toBeUndefined ( )
114
+ } )
115
+
116
+ it ( "sets the cookie expiration and max age to the provided max age from the options" , async ( ) => {
117
+ const maxAge = 60 * 20 // 20 minutes
118
+ cookies . pkceCodeVerifier . options . maxAge = maxAge
119
+
120
+ const pkce = await createPKCE ( options )
121
+
122
+ const expires = new Date ( )
123
+ expires . setTime ( expires . getTime ( ) + maxAge * 1000 )
124
+
125
+ validateCookieExpiration ( { pkce, expires} )
126
+ expect ( pkce ?. cookie . options . maxAge ) . toEqual ( maxAge )
127
+ } )
128
+ } )
129
+
130
+ // comparing the parts instead of getTime() because the milliseconds
131
+ // will not match since the two Date objects are created milliseconds apart
132
+ const validateCookieExpiration = ( { pkce, expires} ) => {
133
+ const cookieExpires = pkce ?. cookie . options . expires
134
+ expect ( cookieExpires . getFullYear ( ) ) . toEqual ( expires . getFullYear ( ) )
135
+ expect ( cookieExpires . getMonth ( ) ) . toEqual ( expires . getMonth ( ) )
136
+ expect ( cookieExpires . getFullYear ( ) ) . toEqual ( expires . getFullYear ( ) )
137
+ expect ( cookieExpires . getHours ( ) ) . toEqual ( expires . getHours ( ) )
138
+ expect ( cookieExpires . getMinutes ( ) ) . toEqual ( expires . getMinutes ( ) )
139
+ }
1 commit comments
vercel[bot] commentedon Dec 1, 2022
Successfully deployed to the following URLs:
next-auth – ./
next-auth-git-main-nextauthjs.vercel.app
next-auth-nextauthjs.vercel.app
www.next-auth.js.org
next-auth-phi-two.vercel.app
next-auth.js.org