1- import adapters from ' ../adapters'
2- import jwt from ' ../lib/jwt'
3- import parseUrl from ' ../lib/parse-url'
4- import logger , { setLogger } from ' ../lib/logger'
5- import * as cookie from ' ./lib/cookie'
6- import * as defaultEvents from ' ./lib/default-events'
7- import * as defaultCallbacks from ' ./lib/default-callbacks'
8- import parseProviders from ' ./lib/providers'
9- import * as routes from ' ./routes'
10- import renderPage from ' ./pages'
11- import createSecret from ' ./lib/create-secret'
12- import callbackUrlHandler from ' ./lib/callback-url-handler'
13- import extendRes from ' ./lib/extend-res'
14- import csrfTokenHandler from ' ./lib/csrf-token-handler'
15- import * as pkce from ' ./lib/oauth/pkce-handler'
16- import * as state from ' ./lib/oauth/state-handler'
1+ import adapters from " ../adapters"
2+ import jwt from " ../lib/jwt"
3+ import parseUrl from " ../lib/parse-url"
4+ import logger , { setLogger } from " ../lib/logger"
5+ import * as cookie from " ./lib/cookie"
6+ import * as defaultEvents from " ./lib/default-events"
7+ import * as defaultCallbacks from " ./lib/default-callbacks"
8+ import parseProviders from " ./lib/providers"
9+ import * as routes from " ./routes"
10+ import renderPage from " ./pages"
11+ import createSecret from " ./lib/create-secret"
12+ import callbackUrlHandler from " ./lib/callback-url-handler"
13+ import extendRes from " ./lib/extend-res"
14+ import csrfTokenHandler from " ./lib/csrf-token-handler"
15+ import * as pkce from " ./lib/oauth/pkce-handler"
16+ import * as state from " ./lib/oauth/state-handler"
1717
1818// To work properly in production with OAuth providers the NEXTAUTH_URL
1919// environment variable must be set.
2020if ( ! process . env . NEXTAUTH_URL ) {
21- logger . warn ( ' NEXTAUTH_URL' , ' NEXTAUTH_URL environment variable not set' )
21+ logger . warn ( " NEXTAUTH_URL" , " NEXTAUTH_URL environment variable not set" )
2222}
2323
2424/**
2525 * @param {import("next").NextApiRequest } req
2626 * @param {import("next").NextApiResponse } res
2727 * @param {import("types").NextAuthOptions } userOptions
2828 */
29- async function NextAuthHandler ( req , res , userOptions ) {
29+ async function NextAuthHandler ( req , res , userOptions ) {
3030 if ( userOptions . logger ) {
3131 setLogger ( userOptions . logger )
3232 }
@@ -39,45 +39,64 @@ async function NextAuthHandler (req, res, userOptions) {
3939 // to avoid early termination of calls to the serverless function
4040 // (and then return that promise when we are done) - eslint
4141 // complains but I'm not sure there is another way to do this.
42- return new Promise ( async resolve => { // eslint-disable-line no-async-promise-executor
42+ // eslint-disable-next-line no-async-promise-executor
43+ return new Promise ( async ( resolve ) => {
4344 extendRes ( req , res , resolve )
4445
4546 if ( ! req . query . nextauth ) {
46- const error = 'Cannot find [...nextauth].js in pages/api/auth. Make sure the filename is written correctly.'
47+ const error =
48+ "Cannot find [...nextauth].js in pages/api/auth. Make sure the filename is written correctly."
4749
48- logger . error ( ' MISSING_NEXTAUTH_API_ROUTE_ERROR' , error )
50+ logger . error ( " MISSING_NEXTAUTH_API_ROUTE_ERROR" , error )
4951 return res . status ( 500 ) . end ( `Error: ${ error } ` )
5052 }
5153
5254 const {
5355 nextauth,
5456 action = nextauth [ 0 ] ,
5557 providerId = nextauth [ 1 ] ,
56- error = nextauth [ 1 ]
58+ error = nextauth [ 1 ] ,
5759 } = req . query
5860
5961 // @todo refactor all existing references to baseUrl and basePath
60- const { basePath, baseUrl } = parseUrl ( process . env . NEXTAUTH_URL || process . env . VERCEL_URL )
62+ const { basePath, baseUrl } = parseUrl (
63+ process . env . NEXTAUTH_URL || process . env . VERCEL_URL
64+ )
6165
6266 const cookies = {
63- ...cookie . defaultCookies ( userOptions . useSecureCookies || baseUrl . startsWith ( 'https://' ) ) ,
67+ ...cookie . defaultCookies (
68+ userOptions . useSecureCookies || baseUrl . startsWith ( "https://" )
69+ ) ,
6470 // Allow user cookie options to override any cookie settings above
65- ...userOptions . cookies
71+ ...userOptions . cookies ,
6672 }
6773
6874 const secret = createSecret ( { userOptions, basePath, baseUrl } )
6975
70- const providers = parseProviders ( { providers : userOptions . providers , baseUrl, basePath } )
76+ const providers = parseProviders ( {
77+ providers : userOptions . providers ,
78+ baseUrl,
79+ basePath,
80+ } )
7181 const provider = providers . find ( ( { id } ) => id === providerId )
7282
7383 // Protection only works on OAuth 2.x providers
74- if ( provider ?. type === 'oauth' && provider . version ?. startsWith ( '2' ) ) {
75- // When provider.state is undefined, we still want this to pass
76- if ( ! provider . protection && provider . state !== false ) {
77- // Default to state, as we did in 3.1 REVIEW: should we use "pkce" or "none" as default?
78- provider . protection = [ 'state' ]
79- } else if ( typeof provider . protection === 'string' ) {
80- provider . protection = [ provider . protection ]
84+ // TODO:
85+ // - rename to `checks` in 4.x, so it is similar to `openid-client`
86+ // - stop supporting `protection` as string
87+ // - remove `state` property
88+ if ( provider ?. type === "oauth" && provider . version ?. startsWith ( "2" ) ) {
89+ // Priority: (protection array > protection string) > state > default
90+ if ( provider . protection ) {
91+ provider . protection = Array . isArray ( provider . protection )
92+ ? provider . protection
93+ : [ provider . protection ]
94+ } else if ( provider . state !== undefined ) {
95+ provider . protection = [ provider . state ? "state" : "none" ]
96+ } else {
97+ // Default to state, as we did in 3.1
98+ // REVIEW: should we use "pkce" or "none" as default?
99+ provider . protection = [ "state" ]
81100 }
82101 }
83102
@@ -86,14 +105,16 @@ async function NextAuthHandler (req, res, userOptions) {
86105 // Parse database / adapter
87106 // If adapter is provided, use it (advanced usage, overrides database)
88107 // If database URI or config object is provided, use it (simple usage)
89- const adapter = userOptions . adapter ?? ( userOptions . database && adapters . Default ( userOptions . database ) )
108+ const adapter =
109+ userOptions . adapter ??
110+ ( userOptions . database && adapters . Default ( userOptions . database ) )
90111
91112 // User provided options are overriden by other options,
92113 // except for the options with special handling above
93114 req . options = {
94115 debug : false ,
95116 pages : { } ,
96- theme : ' auto' ,
117+ theme : " auto" ,
97118 // Custom options override defaults
98119 ...userOptions ,
99120 // These computed settings can have values in userOptions but we override them
@@ -111,28 +132,28 @@ async function NextAuthHandler (req, res, userOptions) {
111132 jwt : ! adapter , // If no adapter specified, force use of JSON Web Tokens (stateless)
112133 maxAge,
113134 updateAge : 24 * 60 * 60 , // Sessions updated only if session is greater than this value (0 = always, 24*60*60 = every 24 hours)
114- ...userOptions . session
135+ ...userOptions . session ,
115136 } ,
116137 // JWT options
117138 jwt : {
118139 secret, // Use application secret if no keys specified
119140 maxAge, // same as session maxAge,
120141 encode : jwt . encode ,
121142 decode : jwt . decode ,
122- ...userOptions . jwt
143+ ...userOptions . jwt ,
123144 } ,
124145 // Event messages
125146 events : {
126147 ...defaultEvents ,
127- ...userOptions . events
148+ ...userOptions . events ,
128149 } ,
129150 // Callback functions
130151 callbacks : {
131152 ...defaultCallbacks ,
132- ...userOptions . callbacks
153+ ...userOptions . callbacks ,
133154 } ,
134155 pkce : { } ,
135- logger
156+ logger,
136157 }
137158
138159 csrfTokenHandler ( req , res )
@@ -141,64 +162,74 @@ async function NextAuthHandler (req, res, userOptions) {
141162 const render = renderPage ( req , res )
142163 const { pages } = req . options
143164
144- if ( req . method === ' GET' ) {
165+ if ( req . method === " GET" ) {
145166 switch ( action ) {
146- case ' providers' :
167+ case " providers" :
147168 return routes . providers ( req , res )
148- case ' session' :
169+ case " session" :
149170 return routes . session ( req , res )
150- case ' csrf' :
171+ case " csrf" :
151172 return res . json ( { csrfToken : req . options . csrfToken } )
152- case ' signin' :
173+ case " signin" :
153174 if ( pages . signIn ) {
154- let signinUrl = `${ pages . signIn } ${ pages . signIn . includes ( '?' ) ? '&' : '?' } callbackUrl=${ req . options . callbackUrl } `
155- if ( error ) { signinUrl = `${ signinUrl } &error=${ error } ` }
175+ let signinUrl = `${ pages . signIn } ${
176+ pages . signIn . includes ( "?" ) ? "&" : "?"
177+ } callbackUrl=${ req . options . callbackUrl } `
178+ if ( error ) {
179+ signinUrl = `${ signinUrl } &error=${ error } `
180+ }
156181 return res . redirect ( signinUrl )
157182 }
158183
159184 return render . signin ( )
160- case ' signout' :
185+ case " signout" :
161186 if ( pages . signOut ) return res . redirect ( pages . signOut )
162187
163188 return render . signout ( )
164- case ' callback' :
189+ case " callback" :
165190 if ( provider ) {
166191 if ( await pkce . handleCallback ( req , res ) ) return
167192 if ( await state . handleCallback ( req , res ) ) return
168193 return routes . callback ( req , res )
169194 }
170195 break
171- case ' verify-request' :
196+ case " verify-request" :
172197 if ( pages . verifyRequest ) {
173198 return res . redirect ( pages . verifyRequest )
174199 }
175200 return render . verifyRequest ( )
176- case ' error' :
201+ case " error" :
177202 if ( pages . error ) {
178- return res . redirect ( `${ pages . error } ${ pages . error . includes ( '?' ) ? '&' : '?' } error=${ error } ` )
203+ return res . redirect (
204+ `${ pages . error } ${
205+ pages . error . includes ( "?" ) ? "&" : "?"
206+ } error=${ error } `
207+ )
179208 }
180209
181210 // These error messages are displayed in line on the sign in page
182- if ( [
183- 'Signin' ,
184- 'OAuthSignin' ,
185- 'OAuthCallback' ,
186- 'OAuthCreateAccount' ,
187- 'EmailCreateAccount' ,
188- 'Callback' ,
189- 'OAuthAccountNotLinked' ,
190- 'EmailSignin' ,
191- 'CredentialsSignin'
192- ] . includes ( error ) ) {
211+ if (
212+ [
213+ "Signin" ,
214+ "OAuthSignin" ,
215+ "OAuthCallback" ,
216+ "OAuthCreateAccount" ,
217+ "EmailCreateAccount" ,
218+ "Callback" ,
219+ "OAuthAccountNotLinked" ,
220+ "EmailSignin" ,
221+ "CredentialsSignin" ,
222+ ] . includes ( error )
223+ ) {
193224 return res . redirect ( `${ baseUrl } ${ basePath } /signin?error=${ error } ` )
194225 }
195226
196227 return render . error ( { error } )
197228 default :
198229 }
199- } else if ( req . method === ' POST' ) {
230+ } else if ( req . method === " POST" ) {
200231 switch ( action ) {
201- case ' signin' :
232+ case " signin" :
202233 // Verified CSRF Token required for all sign in routes
203234 if ( req . options . csrfTokenVerified && provider ) {
204235 if ( await pkce . handleSignin ( req , res ) ) return
@@ -207,16 +238,19 @@ async function NextAuthHandler (req, res, userOptions) {
207238 }
208239
209240 return res . redirect ( `${ baseUrl } ${ basePath } /signin?csrf=true` )
210- case ' signout' :
241+ case " signout" :
211242 // Verified CSRF Token required for signout
212243 if ( req . options . csrfTokenVerified ) {
213244 return routes . signout ( req , res )
214245 }
215246 return res . redirect ( `${ baseUrl } ${ basePath } /signout?csrf=true` )
216- case ' callback' :
247+ case " callback" :
217248 if ( provider ) {
218249 // Verified CSRF Token required for credentials providers only
219- if ( provider . type === 'credentials' && ! req . options . csrfTokenVerified ) {
250+ if (
251+ provider . type === "credentials" &&
252+ ! req . options . csrfTokenVerified
253+ ) {
220254 return res . redirect ( `${ baseUrl } ${ basePath } /signin?csrf=true` )
221255 }
222256
@@ -225,31 +259,33 @@ async function NextAuthHandler (req, res, userOptions) {
225259 return routes . callback ( req , res )
226260 }
227261 break
228- case ' _log' :
262+ case " _log" :
229263 if ( userOptions . logger ) {
230264 try {
231265 const {
232- code = ' CLIENT_ERROR' ,
233- level = ' error' ,
234- message = '[]'
266+ code = " CLIENT_ERROR" ,
267+ level = " error" ,
268+ message = "[]" ,
235269 } = req . body
236270
237271 logger [ level ] ( code , ...JSON . parse ( message ) )
238272 } catch ( error ) {
239273 // If logging itself failed...
240- logger . error ( ' LOGGER_ERROR' , error )
274+ logger . error ( " LOGGER_ERROR" , error )
241275 }
242276 }
243277 return res . end ( )
244278 default :
245279 }
246280 }
247- return res . status ( 400 ) . end ( `Error: HTTP ${ req . method } is not supported for ${ req . url } ` )
281+ return res
282+ . status ( 400 )
283+ . end ( `Error: HTTP ${ req . method } is not supported for ${ req . url } ` )
248284 } )
249285}
250286
251287/** Tha main entry point to next-auth */
252- export default function NextAuth ( ...args ) {
288+ export default function NextAuth ( ...args ) {
253289 if ( args . length === 1 ) {
254290 return ( req , res ) => NextAuthHandler ( req , res , args [ 0 ] )
255291 }
0 commit comments