@descope/nextjs-sdk 0.15.71 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -248,6 +248,10 @@ export default authMiddleware({
248
248
  // Optional: log level for the middleware
249
249
  // Defaults to 'info'
250
250
  // logLevel: 'debug' | 'info' | 'warn' | 'error'
251
+
252
+ // Optional: skip the refresh token validation fallback
253
+ // Defaults to false
254
+ skipRefreshTokenValidation?: boolean
251
255
  })
252
256
 
253
257
  export const config = {
@@ -290,6 +294,29 @@ This setup ensures that you can clearly define which routes in your application
290
294
  };
291
295
  ```
292
296
 
297
+ ##### Skipping Refresh Token Validation
298
+
299
+ By default, when the session token is missing or expired, the middleware falls back to validating the refresh token, and lets the request through if it is valid.
300
+ The middleware does not refresh the session, so server side code that relies on `session()` will still see no valid session.
301
+
302
+ Set `skipRefreshTokenValidation: true` to require a valid session token - requests with only a valid refresh token will be redirected to the sign-in route.
303
+ This is useful when your server side code needs a valid session on every private route.
304
+
305
+ ```typescript
306
+ const options = {
307
+ skipRefreshTokenValidation: true
308
+ };
309
+ ```
310
+
311
+ ###### What the app is expected to do
312
+
313
+ A user with an expired session token and a still valid refresh token is redirected to the sign-in route.
314
+ On the client, `AuthProvider` refreshes the session token from the refresh token on its own (`autoRefresh` is on by default), so the user becomes authenticated again without re-authenticating.
315
+
316
+ Your sign-in page is expected to send an already authenticated user away, otherwise they will sit on it.
317
+ Rendering `<Descope />` with `redirectAfterSuccess` covers this, as does checking `useSession()` and routing away yourself.
318
+ The redirect replaces the original pathname and only carries over its query parameters, so if you want to return the user to the page they came from, capture it yourself before redirecting.
319
+
293
320
  ##### Read session information in server side
294
321
 
295
322
  use the `session()` helper to read session information in Server Components and Route handlers.
@@ -19,6 +19,9 @@ const getSessionJwt = (req, options) => {
19
19
  return undefined;
20
20
  };
21
21
  const getRefreshJwt = (req, options) => {
22
+ if (options?.skipRefreshTokenValidation) {
23
+ return undefined;
24
+ }
22
25
  const refreshJwt = req.cookies?.get(options?.refreshTokenCookieName || 'DSR')?.value;
23
26
  return refreshJwt;
24
27
  };
@@ -1 +1 @@
1
- {"version":3,"file":"authMiddleware.js","sources":["../../../src/server/authMiddleware.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\nimport descopeSdk from '@descope/node-sdk';\nimport { DEFAULT_PUBLIC_ROUTES, DESCOPE_SESSION_HEADER } from './constants';\nimport { getGlobalSdk } from './sdk';\nimport { mergeSearchParams } from './utils';\nimport { LogLevel } from '../types';\nimport { logger, setLogger } from './logger';\n\ntype MiddlewareOptions = {\n\t// The Descope project ID to use for authentication\n\t// Defaults to process.env.NEXT_PUBLIC_DESCOPE_PROJECT_ID\n\tprojectId?: string;\n\n\t// The base URL to use for authentication\n\t// Defaults to process.env.NEXT_PUBLIC_DESCOPE_BASE_URL\n\tbaseUrl?: string;\n\n\t// The URL to redirect to if the user is not authenticated\n\t// Defaults to process.env.SIGN_IN_ROUTE or '/sign-in' if not provided\n\t// NOTE: In case it contains query parameters that exist in the original URL, they will override the original query parameters. e.g. if the original URL is /page?param1=1&param2=2 and the redirect URL is /sign-in?param1=3, the final redirect URL will be /sign-in?param1=3&param2=2\n\tredirectUrl?: string;\n\n\t// An array of public routes that do not require authentication\n\t// In addition to the default public routes:\n\t// - process.env.SIGN_IN_ROUTE or /sign-in if not provided\n\t// - process.env.SIGN_UP_ROUTE or /sign-up if not provided\n\tpublicRoutes?: string[];\n\n\t// An array of private routes that require authentication\n\t// If privateRoutes is defined, routes not listed in this array will default to public routes\n\tprivateRoutes?: string[];\n\n\t// The log level to use for the middleware\n\t// Defaults to 'info'\n\tlogLevel?: LogLevel;\n\n\t// The name of the session cookie to look for the JWT\n\t// Defaults to 'DS'\n\t// Note: The middleware will also look for the JWT in the Authorization header\n\tsessionCookieName?: string;\n\n\t// The name of the refresh token cookie\n\t// Defaults to 'DSR'\n\t// Used to refresh the session when the JWT expires\n\trefreshTokenCookieName?: string;\n};\n\nconst getSessionJwt = (\n\treq: NextRequest,\n\toptions: MiddlewareOptions\n): string | undefined => {\n\tlet jwt = req.headers?.get('Authorization')?.split(' ')[1];\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\n\tjwt = req.cookies?.get(\n\t\toptions?.sessionCookieName || descopeSdk.SessionTokenCookieName\n\t)?.value;\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\treturn undefined;\n};\n\nconst getRefreshJwt = (\n\treq: NextRequest,\n\toptions: MiddlewareOptions\n): string | undefined => {\n\tconst refreshJwt = req.cookies?.get(\n\t\toptions?.refreshTokenCookieName || 'DSR'\n\t)?.value;\n\treturn refreshJwt;\n};\n\nconst matchWildcardRoute = (route: string, path: string) => {\n\tlet regexPattern = route.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n\t// Convert wildcard (*) to match path segments only\n\tregexPattern = regexPattern.replace(/\\*/g, '[^/]*');\n\tconst regex = new RegExp(`^${regexPattern}$`);\n\n\treturn regex.test(path);\n};\n\nconst isPublicRoute = (req: NextRequest, options: MiddlewareOptions) => {\n\t// Ensure publicRoutes and privateRoutes are arrays, defaulting to empty arrays if not defined\n\tconst { publicRoutes = [], privateRoutes = [] } = options;\n\tconst { pathname } = req.nextUrl;\n\n\tconst isDefaultPublicRoute = Object.values(DEFAULT_PUBLIC_ROUTES).includes(\n\t\tpathname\n\t);\n\n\tif (publicRoutes.length > 0) {\n\t\tif (privateRoutes.length > 0) {\n\t\t\tlogger.warn(\n\t\t\t\t'Both publicRoutes and privateRoutes are defined. Ignoring privateRoutes.'\n\t\t\t);\n\t\t}\n\t\treturn (\n\t\t\tisDefaultPublicRoute ||\n\t\t\tpublicRoutes.some((route) => matchWildcardRoute(route, pathname))\n\t\t);\n\t}\n\n\tif (privateRoutes.length > 0) {\n\t\treturn (\n\t\t\tisDefaultPublicRoute ||\n\t\t\t!privateRoutes.some((route) => matchWildcardRoute(route, pathname))\n\t\t);\n\t}\n\n\t// If no routes are provided, all routes are private\n\treturn isDefaultPublicRoute;\n};\n\nconst removeSessionHeader = (headers: Headers): Headers => {\n\tconst requestHeaders = new Headers(headers);\n\trequestHeaders.delete(DESCOPE_SESSION_HEADER);\n\treturn requestHeaders;\n};\n\n// returns a Middleware that checks if the user is authenticated\n// if the user is not authenticated, it redirects to the redirectUrl\nconst createAuthMiddleware =\n\t(options: MiddlewareOptions = {}) =>\n\tasync (req: NextRequest) => {\n\t\tsetLogger(options.logLevel);\n\t\tlogger.debug('[Auth middleware] Starts');\n\n\t\tconst sessionJwt = getSessionJwt(req, options);\n\n\t\t// check if the user is authenticated\n\t\tlet validToken = false;\n\t\ttry {\n\t\t\tawait getGlobalSdk({\n\t\t\t\tprojectId: options.projectId,\n\t\t\t\tbaseUrl: options.baseUrl\n\t\t\t}).validateJwt(sessionJwt);\n\t\t\tvalidToken = true;\n\t\t\tlogger.debug('[Auth middleware] Session JWT is valid');\n\t\t} catch (err) {\n\t\t\tlogger.debug('[Auth middleware] Failed to validate session JWT', err);\n\n\t\t\t// Try to validate the refresh token instead\n\t\t\tconst refreshJwt = getRefreshJwt(req, options);\n\t\t\tif (refreshJwt) {\n\t\t\t\tlogger.debug('[Auth middleware] Attempting to validate refresh token');\n\t\t\t\ttry {\n\t\t\t\t\tawait getGlobalSdk({\n\t\t\t\t\t\tprojectId: options.projectId,\n\t\t\t\t\t\tbaseUrl: options.baseUrl\n\t\t\t\t\t}).validateJwt(refreshJwt);\n\n\t\t\t\t\tlogger.debug('[Auth middleware] Refresh token is valid');\n\t\t\t\t\tvalidToken = true;\n\t\t\t\t} catch (refreshErr) {\n\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t'[Auth middleware] Refresh token validation failed',\n\t\t\t\t\t\trefreshErr\n\t\t\t\t\t);\n\t\t\t\t\t// Refresh token validation failed, continue to redirect logic below\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we don't have a valid session or refresh token and this is a private route, redirect\n\t\t\tif (!validToken && !isPublicRoute(req, options)) {\n\t\t\t\tconst redirectUrl = options.redirectUrl || DEFAULT_PUBLIC_ROUTES.signIn;\n\t\t\t\tconst url = req.nextUrl.clone();\n\t\t\t\t// Create a URL object for redirectUrl. 'http://example.com' is just a placeholder.\n\t\t\t\tconst parsedRedirectUrl = new URL(redirectUrl, 'http://example.com');\n\t\t\t\turl.pathname = parsedRedirectUrl.pathname;\n\n\t\t\t\tconst searchParams = mergeSearchParams(\n\t\t\t\t\turl.search,\n\t\t\t\t\tparsedRedirectUrl.search\n\t\t\t\t);\n\t\t\t\tif (searchParams) {\n\t\t\t\t\turl.search = searchParams;\n\t\t\t\t}\n\t\t\t\tlogger.debug(`[Auth middleware] Redirecting to ${redirectUrl}`);\n\t\t\t\treturn NextResponse.redirect(url);\n\t\t\t}\n\t\t}\n\n\t\tlogger.debug('[Auth middleware] finishes');\n\n\t\tconst headers = removeSessionHeader(req.headers);\n\t\treturn NextResponse.next({\n\t\t\trequest: {\n\t\t\t\theaders\n\t\t\t}\n\t\t});\n\t};\n\nexport default createAuthMiddleware;\n"],"names":["DEFAULT_PUBLIC_ROUTES","logger","DESCOPE_SESSION_HEADER","setLogger","getGlobalSdk","mergeSearchParams","NextResponse"],"mappings":"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"}
1
+ {"version":3,"file":"authMiddleware.js","sources":["../../../src/server/authMiddleware.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\nimport descopeSdk from '@descope/node-sdk';\nimport { DEFAULT_PUBLIC_ROUTES, DESCOPE_SESSION_HEADER } from './constants';\nimport { getGlobalSdk } from './sdk';\nimport { mergeSearchParams } from './utils';\nimport { LogLevel } from '../types';\nimport { logger, setLogger } from './logger';\n\ntype MiddlewareOptions = {\n\t// The Descope project ID to use for authentication\n\t// Defaults to process.env.NEXT_PUBLIC_DESCOPE_PROJECT_ID\n\tprojectId?: string;\n\n\t// The base URL to use for authentication\n\t// Defaults to process.env.NEXT_PUBLIC_DESCOPE_BASE_URL\n\tbaseUrl?: string;\n\n\t// The URL to redirect to if the user is not authenticated\n\t// Defaults to process.env.SIGN_IN_ROUTE or '/sign-in' if not provided\n\t// NOTE: In case it contains query parameters that exist in the original URL, they will override the original query parameters. e.g. if the original URL is /page?param1=1&param2=2 and the redirect URL is /sign-in?param1=3, the final redirect URL will be /sign-in?param1=3&param2=2\n\tredirectUrl?: string;\n\n\t// An array of public routes that do not require authentication\n\t// In addition to the default public routes:\n\t// - process.env.SIGN_IN_ROUTE or /sign-in if not provided\n\t// - process.env.SIGN_UP_ROUTE or /sign-up if not provided\n\tpublicRoutes?: string[];\n\n\t// An array of private routes that require authentication\n\t// If privateRoutes is defined, routes not listed in this array will default to public routes\n\tprivateRoutes?: string[];\n\n\t// The log level to use for the middleware\n\t// Defaults to 'info'\n\tlogLevel?: LogLevel;\n\n\t// The name of the session cookie to look for the JWT\n\t// Defaults to 'DS'\n\t// Note: The middleware will also look for the JWT in the Authorization header\n\tsessionCookieName?: string;\n\n\t// The name of the refresh token cookie\n\t// Defaults to 'DSR'\n\t// Used to refresh the session when the JWT expires\n\trefreshTokenCookieName?: string;\n\n\t// Skip the refresh token validation fallback\n\t// By default, a valid refresh token is enough to pass the middleware even\n\t// when the session token is expired. Set to true to require a valid session\n\t// token, e.g. when server side code relies on `session()`\n\t// Defaults to false\n\tskipRefreshTokenValidation?: boolean;\n};\n\nconst getSessionJwt = (\n\treq: NextRequest,\n\toptions: MiddlewareOptions\n): string | undefined => {\n\tlet jwt = req.headers?.get('Authorization')?.split(' ')[1];\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\n\tjwt = req.cookies?.get(\n\t\toptions?.sessionCookieName || descopeSdk.SessionTokenCookieName\n\t)?.value;\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\treturn undefined;\n};\n\nconst getRefreshJwt = (\n\treq: NextRequest,\n\toptions: MiddlewareOptions\n): string | undefined => {\n\tif (options?.skipRefreshTokenValidation) {\n\t\treturn undefined;\n\t}\n\tconst refreshJwt = req.cookies?.get(\n\t\toptions?.refreshTokenCookieName || 'DSR'\n\t)?.value;\n\treturn refreshJwt;\n};\n\nconst matchWildcardRoute = (route: string, path: string) => {\n\tlet regexPattern = route.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n\t// Convert wildcard (*) to match path segments only\n\tregexPattern = regexPattern.replace(/\\*/g, '[^/]*');\n\tconst regex = new RegExp(`^${regexPattern}$`);\n\n\treturn regex.test(path);\n};\n\nconst isPublicRoute = (req: NextRequest, options: MiddlewareOptions) => {\n\t// Ensure publicRoutes and privateRoutes are arrays, defaulting to empty arrays if not defined\n\tconst { publicRoutes = [], privateRoutes = [] } = options;\n\tconst { pathname } = req.nextUrl;\n\n\tconst isDefaultPublicRoute = Object.values(DEFAULT_PUBLIC_ROUTES).includes(\n\t\tpathname\n\t);\n\n\tif (publicRoutes.length > 0) {\n\t\tif (privateRoutes.length > 0) {\n\t\t\tlogger.warn(\n\t\t\t\t'Both publicRoutes and privateRoutes are defined. Ignoring privateRoutes.'\n\t\t\t);\n\t\t}\n\t\treturn (\n\t\t\tisDefaultPublicRoute ||\n\t\t\tpublicRoutes.some((route) => matchWildcardRoute(route, pathname))\n\t\t);\n\t}\n\n\tif (privateRoutes.length > 0) {\n\t\treturn (\n\t\t\tisDefaultPublicRoute ||\n\t\t\t!privateRoutes.some((route) => matchWildcardRoute(route, pathname))\n\t\t);\n\t}\n\n\t// If no routes are provided, all routes are private\n\treturn isDefaultPublicRoute;\n};\n\nconst removeSessionHeader = (headers: Headers): Headers => {\n\tconst requestHeaders = new Headers(headers);\n\trequestHeaders.delete(DESCOPE_SESSION_HEADER);\n\treturn requestHeaders;\n};\n\n// returns a Middleware that checks if the user is authenticated\n// if the user is not authenticated, it redirects to the redirectUrl\nconst createAuthMiddleware =\n\t(options: MiddlewareOptions = {}) =>\n\tasync (req: NextRequest) => {\n\t\tsetLogger(options.logLevel);\n\t\tlogger.debug('[Auth middleware] Starts');\n\n\t\tconst sessionJwt = getSessionJwt(req, options);\n\n\t\t// check if the user is authenticated\n\t\tlet validToken = false;\n\t\ttry {\n\t\t\tawait getGlobalSdk({\n\t\t\t\tprojectId: options.projectId,\n\t\t\t\tbaseUrl: options.baseUrl\n\t\t\t}).validateJwt(sessionJwt);\n\t\t\tvalidToken = true;\n\t\t\tlogger.debug('[Auth middleware] Session JWT is valid');\n\t\t} catch (err) {\n\t\t\tlogger.debug('[Auth middleware] Failed to validate session JWT', err);\n\n\t\t\t// Try to validate the refresh token instead\n\t\t\tconst refreshJwt = getRefreshJwt(req, options);\n\t\t\tif (refreshJwt) {\n\t\t\t\tlogger.debug('[Auth middleware] Attempting to validate refresh token');\n\t\t\t\ttry {\n\t\t\t\t\tawait getGlobalSdk({\n\t\t\t\t\t\tprojectId: options.projectId,\n\t\t\t\t\t\tbaseUrl: options.baseUrl\n\t\t\t\t\t}).validateJwt(refreshJwt);\n\n\t\t\t\t\tlogger.debug('[Auth middleware] Refresh token is valid');\n\t\t\t\t\tvalidToken = true;\n\t\t\t\t} catch (refreshErr) {\n\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t'[Auth middleware] Refresh token validation failed',\n\t\t\t\t\t\trefreshErr\n\t\t\t\t\t);\n\t\t\t\t\t// Refresh token validation failed, continue to redirect logic below\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we don't have a valid session or refresh token and this is a private route, redirect\n\t\t\tif (!validToken && !isPublicRoute(req, options)) {\n\t\t\t\tconst redirectUrl = options.redirectUrl || DEFAULT_PUBLIC_ROUTES.signIn;\n\t\t\t\tconst url = req.nextUrl.clone();\n\t\t\t\t// Create a URL object for redirectUrl. 'http://example.com' is just a placeholder.\n\t\t\t\tconst parsedRedirectUrl = new URL(redirectUrl, 'http://example.com');\n\t\t\t\turl.pathname = parsedRedirectUrl.pathname;\n\n\t\t\t\tconst searchParams = mergeSearchParams(\n\t\t\t\t\turl.search,\n\t\t\t\t\tparsedRedirectUrl.search\n\t\t\t\t);\n\t\t\t\tif (searchParams) {\n\t\t\t\t\turl.search = searchParams;\n\t\t\t\t}\n\t\t\t\tlogger.debug(`[Auth middleware] Redirecting to ${redirectUrl}`);\n\t\t\t\treturn NextResponse.redirect(url);\n\t\t\t}\n\t\t}\n\n\t\tlogger.debug('[Auth middleware] finishes');\n\n\t\tconst headers = removeSessionHeader(req.headers);\n\t\treturn NextResponse.next({\n\t\t\trequest: {\n\t\t\t\theaders\n\t\t\t}\n\t\t});\n\t};\n\nexport default createAuthMiddleware;\n"],"names":["DEFAULT_PUBLIC_ROUTES","logger","DESCOPE_SESSION_HEADER","setLogger","getGlobalSdk","mergeSearchParams","NextResponse"],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  const DESCOPE_SESSION_HEADER = 'x-descope-session';
4
4
  const baseHeaders = {
5
5
  'x-descope-sdk-name': 'nextjs',
6
- 'x-descope-sdk-version': "0.15.71"
6
+ 'x-descope-sdk-version': "0.16.1"
7
7
  };
8
8
  const DEFAULT_PUBLIC_ROUTES = {
9
9
  signIn: process.env.SIGN_IN_ROUTE || '/sign-in',
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../../../src/server/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\nexport const DESCOPE_SESSION_HEADER = 'x-descope-session';\n\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n\nexport const DEFAULT_PUBLIC_ROUTES = {\n\tsignIn: process.env.SIGN_IN_ROUTE || '/sign-in',\n\tsignUp: process.env.SIGN_UP_ROUTE || '/sign-up'\n};\n"],"names":[],"mappings":";;AAGO,MAAM,sBAAsB,GAAG,oBAAoB;AAE7C,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,SAAa;EACrC;AAEW,MAAA,qBAAqB,GAAG;AACpC,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;AAC/C,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;;;;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../../../src/server/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\nexport const DESCOPE_SESSION_HEADER = 'x-descope-session';\n\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n\nexport const DEFAULT_PUBLIC_ROUTES = {\n\tsignIn: process.env.SIGN_IN_ROUTE || '/sign-in',\n\tsignUp: process.env.SIGN_UP_ROUTE || '/sign-up'\n};\n"],"names":[],"mappings":";;AAGO,MAAM,sBAAsB,GAAG,oBAAoB;AAE7C,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,QAAa;EACrC;AAEW,MAAA,qBAAqB,GAAG;AACpC,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;AAC/C,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;;;;;;;"}
@@ -3,7 +3,7 @@
3
3
  // eslint-disable-next-line import/prefer-default-export
4
4
  const baseHeaders = {
5
5
  'x-descope-sdk-name': 'nextjs',
6
- 'x-descope-sdk-version': "0.15.71"
6
+ 'x-descope-sdk-version': "0.16.1"
7
7
  };
8
8
 
9
9
  exports.baseHeaders = baseHeaders;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../../../src/shared/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\n// eslint-disable-next-line import/prefer-default-export\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n"],"names":[],"mappings":";;AAGA;AACa,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,SAAa;;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../../../src/shared/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\n// eslint-disable-next-line import/prefer-default-export\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n"],"names":[],"mappings":";;AAGA;AACa,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,QAAa;;;;;"}
@@ -17,6 +17,9 @@ const getSessionJwt = (req, options) => {
17
17
  return undefined;
18
18
  };
19
19
  const getRefreshJwt = (req, options) => {
20
+ if (options?.skipRefreshTokenValidation) {
21
+ return undefined;
22
+ }
20
23
  const refreshJwt = req.cookies?.get(options?.refreshTokenCookieName || 'DSR')?.value;
21
24
  return refreshJwt;
22
25
  };
@@ -1 +1 @@
1
- {"version":3,"file":"authMiddleware.js","sources":["../../../src/server/authMiddleware.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\nimport descopeSdk from '@descope/node-sdk';\nimport { DEFAULT_PUBLIC_ROUTES, DESCOPE_SESSION_HEADER } from './constants';\nimport { getGlobalSdk } from './sdk';\nimport { mergeSearchParams } from './utils';\nimport { LogLevel } from '../types';\nimport { logger, setLogger } from './logger';\n\ntype MiddlewareOptions = {\n\t// The Descope project ID to use for authentication\n\t// Defaults to process.env.NEXT_PUBLIC_DESCOPE_PROJECT_ID\n\tprojectId?: string;\n\n\t// The base URL to use for authentication\n\t// Defaults to process.env.NEXT_PUBLIC_DESCOPE_BASE_URL\n\tbaseUrl?: string;\n\n\t// The URL to redirect to if the user is not authenticated\n\t// Defaults to process.env.SIGN_IN_ROUTE or '/sign-in' if not provided\n\t// NOTE: In case it contains query parameters that exist in the original URL, they will override the original query parameters. e.g. if the original URL is /page?param1=1&param2=2 and the redirect URL is /sign-in?param1=3, the final redirect URL will be /sign-in?param1=3&param2=2\n\tredirectUrl?: string;\n\n\t// An array of public routes that do not require authentication\n\t// In addition to the default public routes:\n\t// - process.env.SIGN_IN_ROUTE or /sign-in if not provided\n\t// - process.env.SIGN_UP_ROUTE or /sign-up if not provided\n\tpublicRoutes?: string[];\n\n\t// An array of private routes that require authentication\n\t// If privateRoutes is defined, routes not listed in this array will default to public routes\n\tprivateRoutes?: string[];\n\n\t// The log level to use for the middleware\n\t// Defaults to 'info'\n\tlogLevel?: LogLevel;\n\n\t// The name of the session cookie to look for the JWT\n\t// Defaults to 'DS'\n\t// Note: The middleware will also look for the JWT in the Authorization header\n\tsessionCookieName?: string;\n\n\t// The name of the refresh token cookie\n\t// Defaults to 'DSR'\n\t// Used to refresh the session when the JWT expires\n\trefreshTokenCookieName?: string;\n};\n\nconst getSessionJwt = (\n\treq: NextRequest,\n\toptions: MiddlewareOptions\n): string | undefined => {\n\tlet jwt = req.headers?.get('Authorization')?.split(' ')[1];\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\n\tjwt = req.cookies?.get(\n\t\toptions?.sessionCookieName || descopeSdk.SessionTokenCookieName\n\t)?.value;\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\treturn undefined;\n};\n\nconst getRefreshJwt = (\n\treq: NextRequest,\n\toptions: MiddlewareOptions\n): string | undefined => {\n\tconst refreshJwt = req.cookies?.get(\n\t\toptions?.refreshTokenCookieName || 'DSR'\n\t)?.value;\n\treturn refreshJwt;\n};\n\nconst matchWildcardRoute = (route: string, path: string) => {\n\tlet regexPattern = route.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n\t// Convert wildcard (*) to match path segments only\n\tregexPattern = regexPattern.replace(/\\*/g, '[^/]*');\n\tconst regex = new RegExp(`^${regexPattern}$`);\n\n\treturn regex.test(path);\n};\n\nconst isPublicRoute = (req: NextRequest, options: MiddlewareOptions) => {\n\t// Ensure publicRoutes and privateRoutes are arrays, defaulting to empty arrays if not defined\n\tconst { publicRoutes = [], privateRoutes = [] } = options;\n\tconst { pathname } = req.nextUrl;\n\n\tconst isDefaultPublicRoute = Object.values(DEFAULT_PUBLIC_ROUTES).includes(\n\t\tpathname\n\t);\n\n\tif (publicRoutes.length > 0) {\n\t\tif (privateRoutes.length > 0) {\n\t\t\tlogger.warn(\n\t\t\t\t'Both publicRoutes and privateRoutes are defined. Ignoring privateRoutes.'\n\t\t\t);\n\t\t}\n\t\treturn (\n\t\t\tisDefaultPublicRoute ||\n\t\t\tpublicRoutes.some((route) => matchWildcardRoute(route, pathname))\n\t\t);\n\t}\n\n\tif (privateRoutes.length > 0) {\n\t\treturn (\n\t\t\tisDefaultPublicRoute ||\n\t\t\t!privateRoutes.some((route) => matchWildcardRoute(route, pathname))\n\t\t);\n\t}\n\n\t// If no routes are provided, all routes are private\n\treturn isDefaultPublicRoute;\n};\n\nconst removeSessionHeader = (headers: Headers): Headers => {\n\tconst requestHeaders = new Headers(headers);\n\trequestHeaders.delete(DESCOPE_SESSION_HEADER);\n\treturn requestHeaders;\n};\n\n// returns a Middleware that checks if the user is authenticated\n// if the user is not authenticated, it redirects to the redirectUrl\nconst createAuthMiddleware =\n\t(options: MiddlewareOptions = {}) =>\n\tasync (req: NextRequest) => {\n\t\tsetLogger(options.logLevel);\n\t\tlogger.debug('[Auth middleware] Starts');\n\n\t\tconst sessionJwt = getSessionJwt(req, options);\n\n\t\t// check if the user is authenticated\n\t\tlet validToken = false;\n\t\ttry {\n\t\t\tawait getGlobalSdk({\n\t\t\t\tprojectId: options.projectId,\n\t\t\t\tbaseUrl: options.baseUrl\n\t\t\t}).validateJwt(sessionJwt);\n\t\t\tvalidToken = true;\n\t\t\tlogger.debug('[Auth middleware] Session JWT is valid');\n\t\t} catch (err) {\n\t\t\tlogger.debug('[Auth middleware] Failed to validate session JWT', err);\n\n\t\t\t// Try to validate the refresh token instead\n\t\t\tconst refreshJwt = getRefreshJwt(req, options);\n\t\t\tif (refreshJwt) {\n\t\t\t\tlogger.debug('[Auth middleware] Attempting to validate refresh token');\n\t\t\t\ttry {\n\t\t\t\t\tawait getGlobalSdk({\n\t\t\t\t\t\tprojectId: options.projectId,\n\t\t\t\t\t\tbaseUrl: options.baseUrl\n\t\t\t\t\t}).validateJwt(refreshJwt);\n\n\t\t\t\t\tlogger.debug('[Auth middleware] Refresh token is valid');\n\t\t\t\t\tvalidToken = true;\n\t\t\t\t} catch (refreshErr) {\n\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t'[Auth middleware] Refresh token validation failed',\n\t\t\t\t\t\trefreshErr\n\t\t\t\t\t);\n\t\t\t\t\t// Refresh token validation failed, continue to redirect logic below\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we don't have a valid session or refresh token and this is a private route, redirect\n\t\t\tif (!validToken && !isPublicRoute(req, options)) {\n\t\t\t\tconst redirectUrl = options.redirectUrl || DEFAULT_PUBLIC_ROUTES.signIn;\n\t\t\t\tconst url = req.nextUrl.clone();\n\t\t\t\t// Create a URL object for redirectUrl. 'http://example.com' is just a placeholder.\n\t\t\t\tconst parsedRedirectUrl = new URL(redirectUrl, 'http://example.com');\n\t\t\t\turl.pathname = parsedRedirectUrl.pathname;\n\n\t\t\t\tconst searchParams = mergeSearchParams(\n\t\t\t\t\turl.search,\n\t\t\t\t\tparsedRedirectUrl.search\n\t\t\t\t);\n\t\t\t\tif (searchParams) {\n\t\t\t\t\turl.search = searchParams;\n\t\t\t\t}\n\t\t\t\tlogger.debug(`[Auth middleware] Redirecting to ${redirectUrl}`);\n\t\t\t\treturn NextResponse.redirect(url);\n\t\t\t}\n\t\t}\n\n\t\tlogger.debug('[Auth middleware] finishes');\n\n\t\tconst headers = removeSessionHeader(req.headers);\n\t\treturn NextResponse.next({\n\t\t\trequest: {\n\t\t\t\theaders\n\t\t\t}\n\t\t});\n\t};\n\nexport default createAuthMiddleware;\n"],"names":[],"mappings":";;;;;;;AA+CA,MAAM,aAAa,GAAG,CACrB,GAAgB,EAChB,OAA0B,KACH;AACvB,IAAA,IAAI,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,IAAI,GAAG,EAAE;AACR,QAAA,OAAO,GAAG,CAAC;KACX;AAED,IAAA,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,CACrB,OAAO,EAAE,iBAAiB,IAAI,UAAU,CAAC,sBAAsB,CAC/D,EAAE,KAAK,CAAC;IACT,IAAI,GAAG,EAAE;AACR,QAAA,OAAO,GAAG,CAAC;KACX;AACD,IAAA,OAAO,SAAS,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CACrB,GAAgB,EAChB,OAA0B,KACH;AACvB,IAAA,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,CAClC,OAAO,EAAE,sBAAsB,IAAI,KAAK,CACxC,EAAE,KAAK,CAAC;AACT,IAAA,OAAO,UAAU,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,KAAa,EAAE,IAAY,KAAI;IAC1D,IAAI,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;;IAG/D,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,CAAI,CAAA,EAAA,YAAY,CAAG,CAAA,CAAA,CAAC,CAAC;AAE9C,IAAA,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,GAAgB,EAAE,OAA0B,KAAI;;IAEtE,MAAM,EAAE,YAAY,GAAG,EAAE,EAAE,aAAa,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;AAC1D,IAAA,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;AAEjC,IAAA,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CACzE,QAAQ,CACR,CAAC;AAEF,IAAA,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;AAC5B,QAAA,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;AAC7B,YAAA,MAAM,CAAC,IAAI,CACV,0EAA0E,CAC1E,CAAC;SACF;AACD,QAAA,QACC,oBAAoB;AACpB,YAAA,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,kBAAkB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,EAChE;KACF;AAED,IAAA,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;AAC7B,QAAA,QACC,oBAAoB;AACpB,YAAA,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,kBAAkB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,EAClE;KACF;;AAGD,IAAA,OAAO,oBAAoB,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,OAAgB,KAAa;AACzD,IAAA,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;AAC5C,IAAA,cAAc,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAC9C,IAAA,OAAO,cAAc,CAAC;AACvB,CAAC,CAAC;AAEF;AACA;AACA,MAAM,oBAAoB,GACzB,CAAC,OAAA,GAA6B,EAAE,KAChC,OAAO,GAAgB,KAAI;AAC1B,IAAA,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC5B,IAAA,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;;IAG/C,IAAI,UAAU,GAAG,KAAK,CAAC;AACvB,IAAA,IAAI;AACH,QAAA,MAAM,YAAY,CAAC;YAClB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;AACxB,SAAA,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC3B,UAAU,GAAG,IAAI,CAAC;AAClB,QAAA,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;KACvD;IAAC,OAAO,GAAG,EAAE;AACb,QAAA,MAAM,CAAC,KAAK,CAAC,kDAAkD,EAAE,GAAG,CAAC,CAAC;;QAGtE,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC/C,IAAI,UAAU,EAAE;AACf,YAAA,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;AACvE,YAAA,IAAI;AACH,gBAAA,MAAM,YAAY,CAAC;oBAClB,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;AACxB,iBAAA,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;AAE3B,gBAAA,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;gBACzD,UAAU,GAAG,IAAI,CAAC;aAClB;YAAC,OAAO,UAAU,EAAE;AACpB,gBAAA,MAAM,CAAC,KAAK,CACX,mDAAmD,EACnD,UAAU,CACV,CAAC;;aAEF;SACD;;QAGD,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE;YAChD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,qBAAqB,CAAC,MAAM,CAAC;YACxE,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;;YAEhC,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;AACrE,YAAA,GAAG,CAAC,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,CAAC;AAE1C,YAAA,MAAM,YAAY,GAAG,iBAAiB,CACrC,GAAG,CAAC,MAAM,EACV,iBAAiB,CAAC,MAAM,CACxB,CAAC;YACF,IAAI,YAAY,EAAE;AACjB,gBAAA,GAAG,CAAC,MAAM,GAAG,YAAY,CAAC;aAC1B;AACD,YAAA,MAAM,CAAC,KAAK,CAAC,oCAAoC,WAAW,CAAA,CAAE,CAAC,CAAC;AAChE,YAAA,OAAO,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;SAClC;KACD;AAED,IAAA,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAE3C,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,YAAY,CAAC,IAAI,CAAC;AACxB,QAAA,OAAO,EAAE;YACR,OAAO;AACP,SAAA;AACD,KAAA,CAAC,CAAC;AACJ;;;;"}
1
+ {"version":3,"file":"authMiddleware.js","sources":["../../../src/server/authMiddleware.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server';\nimport descopeSdk from '@descope/node-sdk';\nimport { DEFAULT_PUBLIC_ROUTES, DESCOPE_SESSION_HEADER } from './constants';\nimport { getGlobalSdk } from './sdk';\nimport { mergeSearchParams } from './utils';\nimport { LogLevel } from '../types';\nimport { logger, setLogger } from './logger';\n\ntype MiddlewareOptions = {\n\t// The Descope project ID to use for authentication\n\t// Defaults to process.env.NEXT_PUBLIC_DESCOPE_PROJECT_ID\n\tprojectId?: string;\n\n\t// The base URL to use for authentication\n\t// Defaults to process.env.NEXT_PUBLIC_DESCOPE_BASE_URL\n\tbaseUrl?: string;\n\n\t// The URL to redirect to if the user is not authenticated\n\t// Defaults to process.env.SIGN_IN_ROUTE or '/sign-in' if not provided\n\t// NOTE: In case it contains query parameters that exist in the original URL, they will override the original query parameters. e.g. if the original URL is /page?param1=1&param2=2 and the redirect URL is /sign-in?param1=3, the final redirect URL will be /sign-in?param1=3&param2=2\n\tredirectUrl?: string;\n\n\t// An array of public routes that do not require authentication\n\t// In addition to the default public routes:\n\t// - process.env.SIGN_IN_ROUTE or /sign-in if not provided\n\t// - process.env.SIGN_UP_ROUTE or /sign-up if not provided\n\tpublicRoutes?: string[];\n\n\t// An array of private routes that require authentication\n\t// If privateRoutes is defined, routes not listed in this array will default to public routes\n\tprivateRoutes?: string[];\n\n\t// The log level to use for the middleware\n\t// Defaults to 'info'\n\tlogLevel?: LogLevel;\n\n\t// The name of the session cookie to look for the JWT\n\t// Defaults to 'DS'\n\t// Note: The middleware will also look for the JWT in the Authorization header\n\tsessionCookieName?: string;\n\n\t// The name of the refresh token cookie\n\t// Defaults to 'DSR'\n\t// Used to refresh the session when the JWT expires\n\trefreshTokenCookieName?: string;\n\n\t// Skip the refresh token validation fallback\n\t// By default, a valid refresh token is enough to pass the middleware even\n\t// when the session token is expired. Set to true to require a valid session\n\t// token, e.g. when server side code relies on `session()`\n\t// Defaults to false\n\tskipRefreshTokenValidation?: boolean;\n};\n\nconst getSessionJwt = (\n\treq: NextRequest,\n\toptions: MiddlewareOptions\n): string | undefined => {\n\tlet jwt = req.headers?.get('Authorization')?.split(' ')[1];\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\n\tjwt = req.cookies?.get(\n\t\toptions?.sessionCookieName || descopeSdk.SessionTokenCookieName\n\t)?.value;\n\tif (jwt) {\n\t\treturn jwt;\n\t}\n\treturn undefined;\n};\n\nconst getRefreshJwt = (\n\treq: NextRequest,\n\toptions: MiddlewareOptions\n): string | undefined => {\n\tif (options?.skipRefreshTokenValidation) {\n\t\treturn undefined;\n\t}\n\tconst refreshJwt = req.cookies?.get(\n\t\toptions?.refreshTokenCookieName || 'DSR'\n\t)?.value;\n\treturn refreshJwt;\n};\n\nconst matchWildcardRoute = (route: string, path: string) => {\n\tlet regexPattern = route.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n\t// Convert wildcard (*) to match path segments only\n\tregexPattern = regexPattern.replace(/\\*/g, '[^/]*');\n\tconst regex = new RegExp(`^${regexPattern}$`);\n\n\treturn regex.test(path);\n};\n\nconst isPublicRoute = (req: NextRequest, options: MiddlewareOptions) => {\n\t// Ensure publicRoutes and privateRoutes are arrays, defaulting to empty arrays if not defined\n\tconst { publicRoutes = [], privateRoutes = [] } = options;\n\tconst { pathname } = req.nextUrl;\n\n\tconst isDefaultPublicRoute = Object.values(DEFAULT_PUBLIC_ROUTES).includes(\n\t\tpathname\n\t);\n\n\tif (publicRoutes.length > 0) {\n\t\tif (privateRoutes.length > 0) {\n\t\t\tlogger.warn(\n\t\t\t\t'Both publicRoutes and privateRoutes are defined. Ignoring privateRoutes.'\n\t\t\t);\n\t\t}\n\t\treturn (\n\t\t\tisDefaultPublicRoute ||\n\t\t\tpublicRoutes.some((route) => matchWildcardRoute(route, pathname))\n\t\t);\n\t}\n\n\tif (privateRoutes.length > 0) {\n\t\treturn (\n\t\t\tisDefaultPublicRoute ||\n\t\t\t!privateRoutes.some((route) => matchWildcardRoute(route, pathname))\n\t\t);\n\t}\n\n\t// If no routes are provided, all routes are private\n\treturn isDefaultPublicRoute;\n};\n\nconst removeSessionHeader = (headers: Headers): Headers => {\n\tconst requestHeaders = new Headers(headers);\n\trequestHeaders.delete(DESCOPE_SESSION_HEADER);\n\treturn requestHeaders;\n};\n\n// returns a Middleware that checks if the user is authenticated\n// if the user is not authenticated, it redirects to the redirectUrl\nconst createAuthMiddleware =\n\t(options: MiddlewareOptions = {}) =>\n\tasync (req: NextRequest) => {\n\t\tsetLogger(options.logLevel);\n\t\tlogger.debug('[Auth middleware] Starts');\n\n\t\tconst sessionJwt = getSessionJwt(req, options);\n\n\t\t// check if the user is authenticated\n\t\tlet validToken = false;\n\t\ttry {\n\t\t\tawait getGlobalSdk({\n\t\t\t\tprojectId: options.projectId,\n\t\t\t\tbaseUrl: options.baseUrl\n\t\t\t}).validateJwt(sessionJwt);\n\t\t\tvalidToken = true;\n\t\t\tlogger.debug('[Auth middleware] Session JWT is valid');\n\t\t} catch (err) {\n\t\t\tlogger.debug('[Auth middleware] Failed to validate session JWT', err);\n\n\t\t\t// Try to validate the refresh token instead\n\t\t\tconst refreshJwt = getRefreshJwt(req, options);\n\t\t\tif (refreshJwt) {\n\t\t\t\tlogger.debug('[Auth middleware] Attempting to validate refresh token');\n\t\t\t\ttry {\n\t\t\t\t\tawait getGlobalSdk({\n\t\t\t\t\t\tprojectId: options.projectId,\n\t\t\t\t\t\tbaseUrl: options.baseUrl\n\t\t\t\t\t}).validateJwt(refreshJwt);\n\n\t\t\t\t\tlogger.debug('[Auth middleware] Refresh token is valid');\n\t\t\t\t\tvalidToken = true;\n\t\t\t\t} catch (refreshErr) {\n\t\t\t\t\tlogger.debug(\n\t\t\t\t\t\t'[Auth middleware] Refresh token validation failed',\n\t\t\t\t\t\trefreshErr\n\t\t\t\t\t);\n\t\t\t\t\t// Refresh token validation failed, continue to redirect logic below\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we don't have a valid session or refresh token and this is a private route, redirect\n\t\t\tif (!validToken && !isPublicRoute(req, options)) {\n\t\t\t\tconst redirectUrl = options.redirectUrl || DEFAULT_PUBLIC_ROUTES.signIn;\n\t\t\t\tconst url = req.nextUrl.clone();\n\t\t\t\t// Create a URL object for redirectUrl. 'http://example.com' is just a placeholder.\n\t\t\t\tconst parsedRedirectUrl = new URL(redirectUrl, 'http://example.com');\n\t\t\t\turl.pathname = parsedRedirectUrl.pathname;\n\n\t\t\t\tconst searchParams = mergeSearchParams(\n\t\t\t\t\turl.search,\n\t\t\t\t\tparsedRedirectUrl.search\n\t\t\t\t);\n\t\t\t\tif (searchParams) {\n\t\t\t\t\turl.search = searchParams;\n\t\t\t\t}\n\t\t\t\tlogger.debug(`[Auth middleware] Redirecting to ${redirectUrl}`);\n\t\t\t\treturn NextResponse.redirect(url);\n\t\t\t}\n\t\t}\n\n\t\tlogger.debug('[Auth middleware] finishes');\n\n\t\tconst headers = removeSessionHeader(req.headers);\n\t\treturn NextResponse.next({\n\t\t\trequest: {\n\t\t\t\theaders\n\t\t\t}\n\t\t});\n\t};\n\nexport default createAuthMiddleware;\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  const DESCOPE_SESSION_HEADER = 'x-descope-session';
2
2
  const baseHeaders = {
3
3
  'x-descope-sdk-name': 'nextjs',
4
- 'x-descope-sdk-version': "0.15.71"
4
+ 'x-descope-sdk-version': "0.16.1"
5
5
  };
6
6
  const DEFAULT_PUBLIC_ROUTES = {
7
7
  signIn: process.env.SIGN_IN_ROUTE || '/sign-in',
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../../../src/server/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\nexport const DESCOPE_SESSION_HEADER = 'x-descope-session';\n\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n\nexport const DEFAULT_PUBLIC_ROUTES = {\n\tsignIn: process.env.SIGN_IN_ROUTE || '/sign-in',\n\tsignUp: process.env.SIGN_UP_ROUTE || '/sign-up'\n};\n"],"names":[],"mappings":"AAGO,MAAM,sBAAsB,GAAG,oBAAoB;AAE7C,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,SAAa;EACrC;AAEW,MAAA,qBAAqB,GAAG;AACpC,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;AAC/C,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../../../src/server/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\nexport const DESCOPE_SESSION_HEADER = 'x-descope-session';\n\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n\nexport const DEFAULT_PUBLIC_ROUTES = {\n\tsignIn: process.env.SIGN_IN_ROUTE || '/sign-in',\n\tsignUp: process.env.SIGN_UP_ROUTE || '/sign-up'\n};\n"],"names":[],"mappings":"AAGO,MAAM,sBAAsB,GAAG,oBAAoB;AAE7C,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,QAAa;EACrC;AAEW,MAAA,qBAAqB,GAAG;AACpC,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;AAC/C,IAAA,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU;;;;;"}
@@ -1,7 +1,7 @@
1
1
  // eslint-disable-next-line import/prefer-default-export
2
2
  const baseHeaders = {
3
3
  'x-descope-sdk-name': 'nextjs',
4
- 'x-descope-sdk-version': "0.15.71"
4
+ 'x-descope-sdk-version': "0.16.1"
5
5
  };
6
6
 
7
7
  export { baseHeaders };
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../../../src/shared/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\n// eslint-disable-next-line import/prefer-default-export\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n"],"names":[],"mappings":"AAGA;AACa,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,SAAa;;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../../../src/shared/constants.ts"],"sourcesContent":["// Replaced in build time\ndeclare const BUILD_VERSION: string;\n\n// eslint-disable-next-line import/prefer-default-export\nexport const baseHeaders = {\n\t'x-descope-sdk-name': 'nextjs',\n\t'x-descope-sdk-version': BUILD_VERSION\n};\n"],"names":[],"mappings":"AAGA;AACa,MAAA,WAAW,GAAG;AAC1B,IAAA,oBAAoB,EAAE,QAAQ;AAC9B,IAAA,uBAAuB,EAAE,QAAa;;;;;"}
@@ -9,6 +9,7 @@ type MiddlewareOptions = {
9
9
  logLevel?: LogLevel;
10
10
  sessionCookieName?: string;
11
11
  refreshTokenCookieName?: string;
12
+ skipRefreshTokenValidation?: boolean;
12
13
  };
13
14
  declare const createAuthMiddleware: (options?: MiddlewareOptions) => (req: NextRequest) => Promise<NextResponse<unknown>>;
14
15
  export default createAuthMiddleware;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descope/nextjs-sdk",
3
- "version": "0.15.71",
3
+ "version": "0.16.1",
4
4
  "description": "Descope NextJS SDK",
5
5
  "author": "Descope Team <info@descope.com>",
6
6
  "homepage": "https://github.com/descope/descope-js",
@@ -64,9 +64,9 @@
64
64
  },
65
65
  "dependencies": {
66
66
  "@descope/node-sdk": "2.8.0",
67
- "@descope/react-sdk": "3.3.1",
68
- "@descope/core-js-sdk": "2.70.1",
69
- "@descope/web-component": "4.3.2"
67
+ "@descope/core-js-sdk": "2.71.0",
68
+ "@descope/web-component": "4.3.4",
69
+ "@descope/react-sdk": "3.3.3"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@babel/core": "7.26.0",