@civic/auth 0.13.0 → 0.13.1-beta.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +102 -1
  3. package/dist/lib/analytics.d.ts.map +1 -1
  4. package/dist/lib/jwt.d.ts.map +1 -1
  5. package/dist/lib/logger.d.ts.map +1 -1
  6. package/dist/lib/oauth.d.ts +12 -1
  7. package/dist/lib/oauth.d.ts.map +1 -1
  8. package/dist/lib/oauth.js +29 -1
  9. package/dist/lib/oauth.js.map +1 -1
  10. package/dist/lib/obj.d.ts.map +1 -1
  11. package/dist/lib/postMessage.d.ts.map +1 -1
  12. package/dist/lib/windowUtil.d.ts.map +1 -1
  13. package/dist/nextjs/config.d.ts +2 -11
  14. package/dist/nextjs/config.d.ts.map +1 -1
  15. package/dist/nextjs/config.js.map +1 -1
  16. package/dist/nextjs/cookies.d.ts.map +1 -1
  17. package/dist/nextjs/cookies.js +11 -10
  18. package/dist/nextjs/cookies.js.map +1 -1
  19. package/dist/nextjs/hooks/useInitialAuthConfig.d.ts.map +1 -1
  20. package/dist/nextjs/index.d.ts.map +1 -1
  21. package/dist/nextjs/middleware.d.ts.map +1 -1
  22. package/dist/nextjs/middleware.js +18 -3
  23. package/dist/nextjs/middleware.js.map +1 -1
  24. package/dist/nextjs/providers/NextAuthProviderClient.d.ts.map +1 -1
  25. package/dist/nextjs/routeHandler.d.ts.map +1 -1
  26. package/dist/nextjs/routeHandler.js +21 -92
  27. package/dist/nextjs/routeHandler.js.map +1 -1
  28. package/dist/nextjs/utils.d.ts +9 -3
  29. package/dist/nextjs/utils.d.ts.map +1 -1
  30. package/dist/nextjs/utils.js +20 -61
  31. package/dist/nextjs/utils.js.map +1 -1
  32. package/dist/react-router-7/routeHandler.d.ts.map +1 -1
  33. package/dist/reactjs/components/ButtonContentOrLoader.d.ts.map +1 -1
  34. package/dist/reactjs/components/SignInButton.d.ts.map +1 -1
  35. package/dist/reactjs/components/SignOutButton.d.ts.map +1 -1
  36. package/dist/reactjs/components/UserButton.d.ts.map +1 -1
  37. package/dist/reactjs/components/utils.d.ts.map +1 -1
  38. package/dist/reactjs/hooks/useToken.d.ts.map +1 -1
  39. package/dist/reactjs/hooks/useUser.d.ts.map +1 -1
  40. package/dist/reactjs/styles/colors.d.ts.map +1 -1
  41. package/dist/server/config.d.ts +23 -0
  42. package/dist/server/config.d.ts.map +1 -1
  43. package/dist/server/config.js.map +1 -1
  44. package/dist/server/session.d.ts +57 -0
  45. package/dist/server/session.d.ts.map +1 -1
  46. package/dist/server/session.js +222 -9
  47. package/dist/server/session.js.map +1 -1
  48. package/dist/shared/components/LoadingIcon.d.ts.map +1 -1
  49. package/dist/shared/lib/cookieConfig.d.ts.map +1 -1
  50. package/dist/shared/lib/cookieConfig.js +6 -1
  51. package/dist/shared/lib/cookieConfig.js.map +1 -1
  52. package/dist/shared/lib/iframeUtils.d.ts.map +1 -1
  53. package/dist/shared/lib/session.d.ts.map +1 -1
  54. package/dist/shared/lib/types.d.ts +5 -1
  55. package/dist/shared/lib/types.d.ts.map +1 -1
  56. package/dist/shared/lib/types.js +4 -0
  57. package/dist/shared/lib/types.js.map +1 -1
  58. package/dist/shared/lib/util.d.ts +38 -1
  59. package/dist/shared/lib/util.d.ts.map +1 -1
  60. package/dist/shared/lib/util.js +104 -0
  61. package/dist/shared/lib/util.js.map +1 -1
  62. package/dist/shared/version.d.ts +1 -1
  63. package/dist/shared/version.d.ts.map +1 -1
  64. package/dist/shared/version.js +1 -1
  65. package/dist/shared/version.js.map +1 -1
  66. package/dist/utils.d.ts.map +1 -1
  67. package/dist/vanillajs/auth/handlers/MessageHandler.d.ts.map +1 -1
  68. package/dist/vanillajs/utils/logger.d.ts.map +1 -1
  69. package/package.json +1 -1
@@ -3,9 +3,9 @@ import { NextResponse } from "next/server.js";
3
3
  import { loggers } from "../lib/logger.js";
4
4
  import picomatch from "picomatch";
5
5
  import { AuthFlowCookie, CodeVerifier, OAuthTokenTypes, UserStorage, } from "../shared/lib/types.js";
6
- import { clearTokens, getCookieConfiguration, sanitizeReturnUrl, } from "../shared/lib/util.js";
6
+ import { clearTokens, computeDeepLinkDestination, getCookieConfiguration, sanitizeReturnUrl, } from "../shared/lib/util.js";
7
7
  // Re-export for use by routeHandler
8
- export { sanitizeReturnUrl };
8
+ export { sanitizeReturnUrl, computeDeepLinkDestination };
9
9
  import { CookieStorage } from "../server/index.js";
10
10
  import { extractCookieFromRawHeader } from "../shared/lib/cookieUtils.js";
11
11
  const logger = loggers.nextjs.middleware;
@@ -147,16 +147,16 @@ export class NextjsMiddlewareCookieStorage extends CookieStorage {
147
147
  async delete(key) {
148
148
  // Get cookie configuration for this key to respect the path setting
149
149
  const cookieSettings = this.config?.[key] || {};
150
- // If we have a path configured, use it when deleting the cookie
151
- if (cookieSettings.path) {
152
- this.response.cookies.set(key, "", {
153
- maxAge: 0, // Immediately expire the cookie
154
- path: cookieSettings.path,
155
- });
156
- }
157
- else {
158
- this.response.cookies.delete(key);
159
- }
150
+ // IMPORTANT: Use getCookieConfiguration to match the dynamic secure/sameSite
151
+ // values used when setting the cookie, otherwise the browser won't recognize
152
+ // it as the same cookie and won't delete it.
153
+ const dynamicConfig = getCookieConfiguration(this.request);
154
+ this.response.cookies.set(key, "", {
155
+ maxAge: 0, // Immediately expire the cookie
156
+ path: cookieSettings.path || "/",
157
+ secure: dynamicConfig.secure,
158
+ sameSite: dynamicConfig.sameSite,
159
+ });
160
160
  }
161
161
  }
162
162
  /**
@@ -196,6 +196,7 @@ export const copyCivicCookies = (sourceResponse, targetCall) => {
196
196
  ...Object.values(OAuthTokenTypes),
197
197
  ...Object.values(UserStorage),
198
198
  ...Object.values(CodeVerifier),
199
+ ...Object.values(AuthFlowCookie),
199
200
  ];
200
201
  logger.debug("Copying Civic cookies:", {
201
202
  src: sourceResponse.url,
@@ -210,7 +211,13 @@ export const copyCivicCookies = (sourceResponse, targetCall) => {
210
211
  });
211
212
  };
212
213
  /**
213
- * Handles final authentication logic for unauthenticated users on protected routes
214
+ * Handles final authentication logic for unauthenticated users on protected routes.
215
+ *
216
+ * Note: Deep link cookie setting and auth redirect marker are now handled by
217
+ * CivicAuth.handleDeepLinking which runs earlier in the middleware flow.
218
+ * This function focuses on:
219
+ * 1. Clearing expired/invalid tokens
220
+ * 2. Redirecting to the login URL
214
221
  */
215
222
  export const handleUnauthenticatedUser = async (session, request, response, storage, authConfig) => {
216
223
  // Clear expired/invalid tokens if they exist
@@ -227,54 +234,6 @@ export const handleUnauthenticatedUser = async (session, request, response, stor
227
234
  // The loginUrl from getOriginUrl already includes the basePath, but request.nextUrl.pathname does not. So we strip it off to enable comparison.
228
235
  if (request.nextUrl.pathname !== loginPathWithoutBasePath) {
229
236
  logger.debug(`→ No valid tokens found - redirecting to login "${redirectUrl}"`);
230
- // Preserve the original URL as a deep link for post-authentication redirect
231
- // Apply deepLinkHandling logic here to compute the final redirect URL
232
- if (authConfig.deepLinkHandling !== "disabled") {
233
- const originUrl = getOriginUrl(request, authConfig);
234
- // Get the full path including query string
235
- const fullPath = request.nextUrl.pathname +
236
- request.nextUrl.search +
237
- request.nextUrl.hash;
238
- // Sanitize the return URL to prevent open redirect vulnerabilities
239
- const sanitizedReturnUrl = sanitizeReturnUrl(fullPath, originUrl);
240
- if (sanitizedReturnUrl) {
241
- let returnTo;
242
- if (authConfig.deepLinkHandling === "queryParamsOnly") {
243
- // queryParamsOnly: Merge query params from original URL into loginSuccessUrl
244
- const loginSuccessUrl = authConfig.loginSuccessUrl || "/";
245
- try {
246
- const returnUrlObj = new URL(sanitizedReturnUrl, originUrl);
247
- // If no query params, use loginSuccessUrl directly
248
- if (returnUrlObj.searchParams.size === 0) {
249
- logger.debug(`→ deepLinkHandling=queryParamsOnly: no query params to preserve, using loginSuccessUrl "${loginSuccessUrl}"`);
250
- returnTo = loginSuccessUrl;
251
- }
252
- else {
253
- const baseUrlObj = new URL(loginSuccessUrl, originUrl);
254
- // Append query params from original URL to loginSuccessUrl
255
- returnUrlObj.searchParams.forEach((value, key) => {
256
- baseUrlObj.searchParams.set(key, value);
257
- });
258
- returnTo =
259
- baseUrlObj.pathname + baseUrlObj.search + baseUrlObj.hash;
260
- logger.debug(`→ deepLinkHandling=queryParamsOnly: merged params into "${returnTo}"`);
261
- }
262
- }
263
- catch {
264
- // If URL parsing fails, fall back to loginSuccessUrl
265
- logger.warn(`→ Failed to merge query params, falling back to loginSuccessUrl`);
266
- returnTo = loginSuccessUrl;
267
- }
268
- }
269
- else {
270
- // fullUrl: Use the full path directly
271
- returnTo = sanitizedReturnUrl;
272
- logger.debug(`→ deepLinkHandling=fullUrl: preserving deep link "${returnTo}"`);
273
- }
274
- // Set the cookie with the computed return URL
275
- await storage.set(AuthFlowCookie.RETURN_URL, returnTo, {});
276
- }
277
- }
278
237
  const redirectedResponse = redirectWithBasePath(authConfig, redirectUrl);
279
238
  // Copy any cookies that were set to the redirect response
280
239
  response.cookies.getAll().forEach((cookie) => {
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/nextjs/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n systemUrlsConfig,\n type AuthConfig,\n type AuthConfigWithDefaults,\n} from \"@/nextjs/config.js\";\nimport type { NextRequest } from \"next/server.js\";\nimport { NextResponse } from \"next/server.js\";\nimport type { SessionData } from \"@/types.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport picomatch from \"picomatch\";\nimport {\n AuthFlowCookie,\n CodeVerifier,\n OAuthTokenTypes,\n UserStorage,\n type CookieConfig,\n type KeySetter,\n} from \"@/shared/lib/types.js\";\nimport {\n clearTokens,\n getCookieConfiguration,\n sanitizeReturnUrl,\n} from \"@/shared/lib/util.js\";\n\n// Re-export for use by routeHandler\nexport { sanitizeReturnUrl };\nimport { CookieStorage } from \"@/server/index.js\";\nimport { extractCookieFromRawHeader } from \"@/shared/lib/cookieUtils.js\";\n\nconst logger = loggers.nextjs.middleware;\n\nexport const resolveCallbackUrl = (\n config: AuthConfigWithDefaults,\n baseUrl?: string,\n): string => {\n const callbackUrl = new URL(config?.callbackUrl, baseUrl).toString();\n return callbackUrl.toString();\n};\n\nexport function sanitizeBasePath(path: string): string {\n if (!path || path === \"/\") return \"\";\n\n // Ensure it starts with a slash\n const withLeadingSlash = path.startsWith(\"/\") ? path : `/${path}`;\n\n // Remove all trailing slashes (not just one)\n return withLeadingSlash.replace(/\\/+$/, \"\");\n}\n\n/**\n * Removes the basePath prefix from a pathname, properly handling edge cases\n * This is the inverse operation of adding basePath to a URL\n */\nexport function removeBasePathFromPath(\n pathname: string,\n basePath?: string,\n): string {\n if (!basePath || basePath === \"\" || basePath === \"/\") {\n return pathname;\n }\n\n // Sanitize the basePath to ensure consistent format\n const sanitizedBasePath = sanitizeBasePath(basePath);\n\n // Check if pathname starts with the basePath followed by a slash or end of string\n // This prevents partial matches like \"/app\" matching \"/application\"\n if (pathname === sanitizedBasePath) {\n // Exact match - return root\n return \"/\";\n } else if (pathname.startsWith(sanitizedBasePath + \"/\")) {\n // basePath followed by slash - remove basePath but keep the slash\n return pathname.slice(sanitizedBasePath.length);\n }\n\n // If basePath doesn't match as a complete path segment, return pathname as-is\n return pathname;\n}\n\nexport const getOriginUrl = (\n request: NextRequest,\n authConfig: AuthConfigWithDefaults,\n): string => {\n // Use configured baseUrl if provided (for reverse proxy scenarios)\n if (authConfig.baseUrl) {\n return authConfig.baseUrl;\n }\n\n // Fallback to nextUrl.origin (includes port automatically)\n return request.nextUrl.origin;\n};\n\n// Matches globs:\n// Examples:\n// /user\n// /user/*\n// /user/**/info\nconst matchGlob = (pathname: string, globPattern: string) => {\n const matches = picomatch(globPattern);\n return matches(pathname);\n};\n\nconst matchesGlobs = (pathname: string, patterns: string[]) =>\n patterns.some((pattern) => {\n if (!pattern) return false;\n return matchGlob(pathname, pattern);\n });\n\n/**\n * Determines if we should attempt token refresh based on session state\n */\nexport const shouldAttemptRefresh = (session: SessionData): boolean => {\n return !session.authenticated && !!session.refreshToken;\n};\n\nconst stripBasePathPrefix = (path: string, basePath: string = \"\") => {\n return path.replace(new RegExp(`^${basePath}`), \"\");\n};\n/**\n * Checks if the current path is a system URL that should skip auth\n */\nexport const shouldSkipAuthForSystemUrls = (\n pathname: string,\n authConfig: AuthConfigWithDefaults,\n): boolean => {\n // make an array of all system URLs from authConfig using the systemUrlsConfig keys\n const systemUrls = Object.keys(systemUrlsConfig).map(\n (key) => authConfig[key as keyof AuthConfigWithDefaults] as string,\n );\n\n // check if any of the urls in systemUrls has a substring match with pathname\n // the systemUrl or incoming path could have a basePath, i.e. /dashboard/api/auth/callback\n // therefore we check if the systemUrl equals the pathname after stripping the basePath prefix\n const strippedPathname = stripBasePathPrefix(pathname, authConfig.basePath);\n const strippedSystemUrls = systemUrls.map((url) =>\n stripBasePathPrefix(url, authConfig.basePath),\n );\n const isSystemUrl = strippedSystemUrls.some(\n (url) => url && pathname && pathname !== \"/\" && url === strippedPathname,\n );\n logger.debug(\"→ isSystemUrl check\", { pathname, isSystemUrl, systemUrls });\n if (isSystemUrl) {\n logger.debug(\n \"→ Skipping auth check - this a URL defined in authConfig\",\n pathname,\n );\n }\n\n return isSystemUrl;\n};\n\n/**\n * CookieStorage implementation for NextJS middleware context that works with NextRequest\n */\nexport class NextjsMiddlewareCookieStorage extends CookieStorage {\n constructor(\n public config: Partial<Record<KeySetter, CookieConfig>> = {},\n private request: NextRequest,\n private response: NextResponse,\n ) {\n super({\n secure: true,\n httpOnly: true,\n });\n }\n\n async get(key: string): Promise<string | null> {\n // First try to get cookies from the response if it has already been set\n const cookieValue = this.response.cookies.get(key)?.value;\n if (cookieValue) {\n return cookieValue;\n }\n\n const cookieSettings = this.config?.[key as KeySetter] || {};\n const configuredPath = cookieSettings.path;\n\n // If we have a non-root basePath, use raw header parsing to get the first cookie\n // which should be from the most specific path, avoiding duplicate cookie conflicts\n if (configuredPath && configuredPath !== \"/\") {\n const cookieHeader = this.request.headers.get(\"cookie\");\n const rawValue = extractCookieFromRawHeader(cookieHeader, key);\n if (rawValue) {\n return rawValue;\n }\n }\n\n // Fallback to standard Next.js request cookies\n return this.request.cookies.get(key)?.value || null;\n }\n\n async set(\n key: string,\n value: string,\n cookieConfigOverride: CookieConfig,\n ): Promise<void> {\n const cookieSettings = this.config?.[key as KeySetter] || {\n ...this.settings,\n };\n const dynamicConfig = getCookieConfiguration(this.request);\n\n const useCookieSettings = {\n ...cookieSettings,\n ...cookieConfigOverride,\n // Apply dynamic configuration for secure and sameSite\n secure: dynamicConfig.secure,\n sameSite: dynamicConfig.sameSite,\n };\n\n // Respect the httpOnly setting from configuration instead of hardcoding it\n this.response.cookies.set(key, value, useCookieSettings);\n }\n\n async delete(key: string): Promise<void> {\n // Get cookie configuration for this key to respect the path setting\n const cookieSettings = this.config?.[key as KeySetter] || {};\n\n // If we have a path configured, use it when deleting the cookie\n if (cookieSettings.path) {\n this.response.cookies.set(key, \"\", {\n maxAge: 0, // Immediately expire the cookie\n path: cookieSettings.path,\n });\n } else {\n this.response.cookies.delete(key);\n }\n }\n}\n\n/**\n * Handles authentication logic specifically for the login URL\n * Provides logging for login URL access patterns\n */\nexport const handleLoginUrl = (\n pathname: string,\n session: SessionData,\n authConfig: AuthConfigWithDefaults,\n): void => {\n if (pathname !== authConfig.loginUrl) {\n return;\n }\n\n // We are on the login URL - log the access pattern\n if (session.authenticated) {\n logger.debug(`→ Authenticated user accessing login page`);\n } else {\n logger.debug(`→ Unauthenticated user accessing login page`);\n }\n};\n\n/**\n * Checks if the current path should skip auth based on include/exclude patterns\n */\nexport const shouldSkipAuthForRoutePatterns = (\n pathname: string,\n authConfig: AuthConfigWithDefaults,\n): boolean => {\n // Check include patterns\n if (!matchesGlobs(pathname, authConfig.include)) {\n logger.debug(\n \"→ Skipping auth check - path not in include patterns\",\n pathname,\n );\n return true;\n }\n\n // Check exclude patterns\n if (matchesGlobs(pathname, authConfig.exclude)) {\n logger.debug(\"→ Skipping auth check - path in exclude patterns\", pathname);\n return true;\n }\n\n return false;\n};\n\nexport const copyCivicCookies = (\n sourceResponse: NextResponse,\n targetCall: NextResponse | NextRequest,\n) => {\n const civicCookieNames = [\n ...Object.values(OAuthTokenTypes),\n ...Object.values(UserStorage),\n ...Object.values(CodeVerifier),\n ];\n logger.debug(\"Copying Civic cookies:\", {\n src: sourceResponse.url,\n target: targetCall.url,\n });\n sourceResponse?.cookies\n .getAll()\n .filter((cookie) =>\n civicCookieNames.includes(cookie.name as OAuthTokenTypes),\n )\n .forEach((cookie) => {\n logger.debug(\"Setting middlewareResponse cookie:\", cookie);\n targetCall.cookies.set(cookie);\n });\n};\n/**\n * Handles final authentication logic for unauthenticated users on protected routes\n */\nexport const handleUnauthenticatedUser = async (\n session: SessionData,\n request: NextRequest,\n response: NextResponse,\n storage: NextjsMiddlewareCookieStorage,\n authConfig: AuthConfigWithDefaults,\n): Promise<NextResponse | undefined> => {\n // Clear expired/invalid tokens if they exist\n if (session.accessToken || session.idToken || session.refreshToken) {\n logger.debug(`→ Clearing expired/invalid tokens`);\n await clearTokens(storage);\n }\n\n // Final fallback: redirect to login unless we're already there.\n const loginUrl = new URL(\n authConfig.loginUrl,\n getOriginUrl(request, authConfig),\n );\n const redirectUrl = `${loginUrl.toString()}`;\n const loginPathWithoutBasePath = removeBasePathFromPath(\n loginUrl.pathname,\n authConfig.basePath,\n );\n\n // If we're already at the login URL, the middleware will just return undefined.\n // This is to prevent an infinite redirect loop if middleware is applied to the login route itself.\n // The loginUrl from getOriginUrl already includes the basePath, but request.nextUrl.pathname does not. So we strip it off to enable comparison.\n if (request.nextUrl.pathname !== loginPathWithoutBasePath) {\n logger.debug(\n `→ No valid tokens found - redirecting to login \"${redirectUrl}\"`,\n );\n\n // Preserve the original URL as a deep link for post-authentication redirect\n // Apply deepLinkHandling logic here to compute the final redirect URL\n if (authConfig.deepLinkHandling !== \"disabled\") {\n const originUrl = getOriginUrl(request, authConfig);\n // Get the full path including query string\n const fullPath =\n request.nextUrl.pathname +\n request.nextUrl.search +\n request.nextUrl.hash;\n\n // Sanitize the return URL to prevent open redirect vulnerabilities\n const sanitizedReturnUrl = sanitizeReturnUrl(fullPath, originUrl);\n\n if (sanitizedReturnUrl) {\n let returnTo: string;\n\n if (authConfig.deepLinkHandling === \"queryParamsOnly\") {\n // queryParamsOnly: Merge query params from original URL into loginSuccessUrl\n const loginSuccessUrl = authConfig.loginSuccessUrl || \"/\";\n try {\n const returnUrlObj = new URL(sanitizedReturnUrl, originUrl);\n\n // If no query params, use loginSuccessUrl directly\n if (returnUrlObj.searchParams.size === 0) {\n logger.debug(\n `→ deepLinkHandling=queryParamsOnly: no query params to preserve, using loginSuccessUrl \"${loginSuccessUrl}\"`,\n );\n returnTo = loginSuccessUrl;\n } else {\n const baseUrlObj = new URL(loginSuccessUrl, originUrl);\n\n // Append query params from original URL to loginSuccessUrl\n returnUrlObj.searchParams.forEach((value, key) => {\n baseUrlObj.searchParams.set(key, value);\n });\n\n returnTo =\n baseUrlObj.pathname + baseUrlObj.search + baseUrlObj.hash;\n logger.debug(\n `→ deepLinkHandling=queryParamsOnly: merged params into \"${returnTo}\"`,\n );\n }\n } catch {\n // If URL parsing fails, fall back to loginSuccessUrl\n logger.warn(\n `→ Failed to merge query params, falling back to loginSuccessUrl`,\n );\n returnTo = loginSuccessUrl;\n }\n } else {\n // fullUrl: Use the full path directly\n returnTo = sanitizedReturnUrl;\n logger.debug(\n `→ deepLinkHandling=fullUrl: preserving deep link \"${returnTo}\"`,\n );\n }\n\n // Set the cookie with the computed return URL\n await storage.set(AuthFlowCookie.RETURN_URL, returnTo, {});\n }\n }\n\n const redirectedResponse = redirectWithBasePath(authConfig, redirectUrl);\n // Copy any cookies that were set to the redirect response\n response.cookies.getAll().forEach((cookie) => {\n redirectedResponse.cookies.set(cookie);\n });\n return redirectedResponse;\n }\n\n return response;\n};\n\n/**\n * Prepends the basePath onto a given URL if it's not already there. Works for both relative and absolute URLs.\n * @param url\n * @param basePath\n * @returns\n */\nexport const prependBasePath = (url: string, basePath: string) => {\n basePath = \"/\" + basePath.replace(/^\\/|\\/$/g, \"\"); // normalize basePath\n\n const isAbsolute = /^https?:\\/\\//.test(url);\n\n if (isAbsolute) {\n const u = new URL(url);\n if (!u.pathname.startsWith(basePath)) {\n u.pathname =\n basePath + (u.pathname.startsWith(\"/\") ? \"\" : \"/\") + u.pathname;\n }\n return u.toString();\n }\n\n return url.startsWith(basePath)\n ? url\n : basePath + (url.startsWith(\"/\") ? \"\" : \"/\") + url;\n};\n\nexport const redirectWithBasePath = (\n config: AuthConfig,\n targetUrl: string,\n): NextResponse =>\n NextResponse.redirect(prependBasePath(targetUrl, config.basePath || \"\"));\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/nextjs/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n systemUrlsConfig,\n type AuthConfig,\n type AuthConfigWithDefaults,\n} from \"@/nextjs/config.js\";\nimport type { NextRequest } from \"next/server.js\";\nimport { NextResponse } from \"next/server.js\";\nimport type { SessionData } from \"@/types.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport picomatch from \"picomatch\";\nimport {\n AuthFlowCookie,\n CodeVerifier,\n OAuthTokenTypes,\n UserStorage,\n type CookieConfig,\n type KeySetter,\n} from \"@/shared/lib/types.js\";\nimport {\n clearTokens,\n computeDeepLinkDestination,\n getCookieConfiguration,\n sanitizeReturnUrl,\n} from \"@/shared/lib/util.js\";\n\n// Re-export for use by routeHandler\nexport { sanitizeReturnUrl, computeDeepLinkDestination };\nimport { CookieStorage } from \"@/server/index.js\";\nimport { extractCookieFromRawHeader } from \"@/shared/lib/cookieUtils.js\";\n\nconst logger = loggers.nextjs.middleware;\n\nexport const resolveCallbackUrl = (\n config: AuthConfigWithDefaults,\n baseUrl?: string,\n): string => {\n const callbackUrl = new URL(config?.callbackUrl, baseUrl).toString();\n return callbackUrl.toString();\n};\n\nexport function sanitizeBasePath(path: string): string {\n if (!path || path === \"/\") return \"\";\n\n // Ensure it starts with a slash\n const withLeadingSlash = path.startsWith(\"/\") ? path : `/${path}`;\n\n // Remove all trailing slashes (not just one)\n return withLeadingSlash.replace(/\\/+$/, \"\");\n}\n\n/**\n * Removes the basePath prefix from a pathname, properly handling edge cases\n * This is the inverse operation of adding basePath to a URL\n */\nexport function removeBasePathFromPath(\n pathname: string,\n basePath?: string,\n): string {\n if (!basePath || basePath === \"\" || basePath === \"/\") {\n return pathname;\n }\n\n // Sanitize the basePath to ensure consistent format\n const sanitizedBasePath = sanitizeBasePath(basePath);\n\n // Check if pathname starts with the basePath followed by a slash or end of string\n // This prevents partial matches like \"/app\" matching \"/application\"\n if (pathname === sanitizedBasePath) {\n // Exact match - return root\n return \"/\";\n } else if (pathname.startsWith(sanitizedBasePath + \"/\")) {\n // basePath followed by slash - remove basePath but keep the slash\n return pathname.slice(sanitizedBasePath.length);\n }\n\n // If basePath doesn't match as a complete path segment, return pathname as-is\n return pathname;\n}\n\nexport const getOriginUrl = (\n request: NextRequest,\n authConfig: AuthConfigWithDefaults,\n): string => {\n // Use configured baseUrl if provided (for reverse proxy scenarios)\n if (authConfig.baseUrl) {\n return authConfig.baseUrl;\n }\n\n // Fallback to nextUrl.origin (includes port automatically)\n return request.nextUrl.origin;\n};\n\n// Matches globs:\n// Examples:\n// /user\n// /user/*\n// /user/**/info\nconst matchGlob = (pathname: string, globPattern: string) => {\n const matches = picomatch(globPattern);\n return matches(pathname);\n};\n\nconst matchesGlobs = (pathname: string, patterns: string[]) =>\n patterns.some((pattern) => {\n if (!pattern) return false;\n return matchGlob(pathname, pattern);\n });\n\n/**\n * Determines if we should attempt token refresh based on session state\n */\nexport const shouldAttemptRefresh = (session: SessionData): boolean => {\n return !session.authenticated && !!session.refreshToken;\n};\n\nconst stripBasePathPrefix = (path: string, basePath: string = \"\") => {\n return path.replace(new RegExp(`^${basePath}`), \"\");\n};\n/**\n * Checks if the current path is a system URL that should skip auth\n */\nexport const shouldSkipAuthForSystemUrls = (\n pathname: string,\n authConfig: AuthConfigWithDefaults,\n): boolean => {\n // make an array of all system URLs from authConfig using the systemUrlsConfig keys\n const systemUrls = Object.keys(systemUrlsConfig).map(\n (key) => authConfig[key as keyof AuthConfigWithDefaults] as string,\n );\n\n // check if any of the urls in systemUrls has a substring match with pathname\n // the systemUrl or incoming path could have a basePath, i.e. /dashboard/api/auth/callback\n // therefore we check if the systemUrl equals the pathname after stripping the basePath prefix\n const strippedPathname = stripBasePathPrefix(pathname, authConfig.basePath);\n const strippedSystemUrls = systemUrls.map((url) =>\n stripBasePathPrefix(url, authConfig.basePath),\n );\n const isSystemUrl = strippedSystemUrls.some(\n (url) => url && pathname && pathname !== \"/\" && url === strippedPathname,\n );\n logger.debug(\"→ isSystemUrl check\", { pathname, isSystemUrl, systemUrls });\n if (isSystemUrl) {\n logger.debug(\n \"→ Skipping auth check - this a URL defined in authConfig\",\n pathname,\n );\n }\n\n return isSystemUrl;\n};\n\n/**\n * CookieStorage implementation for NextJS middleware context that works with NextRequest\n */\nexport class NextjsMiddlewareCookieStorage extends CookieStorage {\n constructor(\n public config: Partial<Record<KeySetter, CookieConfig>> = {},\n private request: NextRequest,\n private response: NextResponse,\n ) {\n super({\n secure: true,\n httpOnly: true,\n });\n }\n\n async get(key: string): Promise<string | null> {\n // First try to get cookies from the response if it has already been set\n const cookieValue = this.response.cookies.get(key)?.value;\n if (cookieValue) {\n return cookieValue;\n }\n\n const cookieSettings = this.config?.[key as KeySetter] || {};\n const configuredPath = cookieSettings.path;\n\n // If we have a non-root basePath, use raw header parsing to get the first cookie\n // which should be from the most specific path, avoiding duplicate cookie conflicts\n if (configuredPath && configuredPath !== \"/\") {\n const cookieHeader = this.request.headers.get(\"cookie\");\n const rawValue = extractCookieFromRawHeader(cookieHeader, key);\n if (rawValue) {\n return rawValue;\n }\n }\n\n // Fallback to standard Next.js request cookies\n return this.request.cookies.get(key)?.value || null;\n }\n\n async set(\n key: string,\n value: string,\n cookieConfigOverride: CookieConfig,\n ): Promise<void> {\n const cookieSettings = this.config?.[key as KeySetter] || {\n ...this.settings,\n };\n const dynamicConfig = getCookieConfiguration(this.request);\n\n const useCookieSettings = {\n ...cookieSettings,\n ...cookieConfigOverride,\n // Apply dynamic configuration for secure and sameSite\n secure: dynamicConfig.secure,\n sameSite: dynamicConfig.sameSite,\n };\n\n // Respect the httpOnly setting from configuration instead of hardcoding it\n this.response.cookies.set(key, value, useCookieSettings);\n }\n\n async delete(key: string): Promise<void> {\n // Get cookie configuration for this key to respect the path setting\n const cookieSettings = this.config?.[key as KeySetter] || {};\n // IMPORTANT: Use getCookieConfiguration to match the dynamic secure/sameSite\n // values used when setting the cookie, otherwise the browser won't recognize\n // it as the same cookie and won't delete it.\n const dynamicConfig = getCookieConfiguration(this.request);\n\n this.response.cookies.set(key, \"\", {\n maxAge: 0, // Immediately expire the cookie\n path: cookieSettings.path || \"/\",\n secure: dynamicConfig.secure,\n sameSite: dynamicConfig.sameSite,\n });\n }\n}\n\n/**\n * Handles authentication logic specifically for the login URL\n * Provides logging for login URL access patterns\n */\nexport const handleLoginUrl = (\n pathname: string,\n session: SessionData,\n authConfig: AuthConfigWithDefaults,\n): void => {\n if (pathname !== authConfig.loginUrl) {\n return;\n }\n\n // We are on the login URL - log the access pattern\n if (session.authenticated) {\n logger.debug(`→ Authenticated user accessing login page`);\n } else {\n logger.debug(`→ Unauthenticated user accessing login page`);\n }\n};\n\n/**\n * Checks if the current path should skip auth based on include/exclude patterns\n */\nexport const shouldSkipAuthForRoutePatterns = (\n pathname: string,\n authConfig: AuthConfigWithDefaults,\n): boolean => {\n // Check include patterns\n if (!matchesGlobs(pathname, authConfig.include)) {\n logger.debug(\n \"→ Skipping auth check - path not in include patterns\",\n pathname,\n );\n return true;\n }\n\n // Check exclude patterns\n if (matchesGlobs(pathname, authConfig.exclude)) {\n logger.debug(\"→ Skipping auth check - path in exclude patterns\", pathname);\n return true;\n }\n\n return false;\n};\n\nexport const copyCivicCookies = (\n sourceResponse: NextResponse,\n targetCall: NextResponse | NextRequest,\n) => {\n const civicCookieNames = [\n ...Object.values(OAuthTokenTypes),\n ...Object.values(UserStorage),\n ...Object.values(CodeVerifier),\n ...Object.values(AuthFlowCookie),\n ];\n logger.debug(\"Copying Civic cookies:\", {\n src: sourceResponse.url,\n target: targetCall.url,\n });\n sourceResponse?.cookies\n .getAll()\n .filter((cookie) =>\n civicCookieNames.includes(cookie.name as OAuthTokenTypes),\n )\n .forEach((cookie) => {\n logger.debug(\"Setting middlewareResponse cookie:\", cookie);\n targetCall.cookies.set(cookie);\n });\n};\n\n/**\n * Handles final authentication logic for unauthenticated users on protected routes.\n *\n * Note: Deep link cookie setting and auth redirect marker are now handled by\n * CivicAuth.handleDeepLinking which runs earlier in the middleware flow.\n * This function focuses on:\n * 1. Clearing expired/invalid tokens\n * 2. Redirecting to the login URL\n */\nexport const handleUnauthenticatedUser = async (\n session: SessionData,\n request: NextRequest,\n response: NextResponse,\n storage: NextjsMiddlewareCookieStorage,\n authConfig: AuthConfigWithDefaults,\n): Promise<NextResponse | undefined> => {\n // Clear expired/invalid tokens if they exist\n if (session.accessToken || session.idToken || session.refreshToken) {\n logger.debug(`→ Clearing expired/invalid tokens`);\n await clearTokens(storage);\n }\n\n // Final fallback: redirect to login unless we're already there.\n const loginUrl = new URL(\n authConfig.loginUrl,\n getOriginUrl(request, authConfig),\n );\n const redirectUrl = `${loginUrl.toString()}`;\n const loginPathWithoutBasePath = removeBasePathFromPath(\n loginUrl.pathname,\n authConfig.basePath,\n );\n\n // If we're already at the login URL, the middleware will just return undefined.\n // This is to prevent an infinite redirect loop if middleware is applied to the login route itself.\n // The loginUrl from getOriginUrl already includes the basePath, but request.nextUrl.pathname does not. So we strip it off to enable comparison.\n if (request.nextUrl.pathname !== loginPathWithoutBasePath) {\n logger.debug(\n `→ No valid tokens found - redirecting to login \"${redirectUrl}\"`,\n );\n\n const redirectedResponse = redirectWithBasePath(authConfig, redirectUrl);\n // Copy any cookies that were set to the redirect response\n response.cookies.getAll().forEach((cookie) => {\n redirectedResponse.cookies.set(cookie);\n });\n return redirectedResponse;\n }\n\n return response;\n};\n\n/**\n * Prepends the basePath onto a given URL if it's not already there. Works for both relative and absolute URLs.\n * @param url\n * @param basePath\n * @returns\n */\nexport const prependBasePath = (url: string, basePath: string) => {\n basePath = \"/\" + basePath.replace(/^\\/|\\/$/g, \"\"); // normalize basePath\n\n const isAbsolute = /^https?:\\/\\//.test(url);\n\n if (isAbsolute) {\n const u = new URL(url);\n if (!u.pathname.startsWith(basePath)) {\n u.pathname =\n basePath + (u.pathname.startsWith(\"/\") ? \"\" : \"/\") + u.pathname;\n }\n return u.toString();\n }\n\n return url.startsWith(basePath)\n ? url\n : basePath + (url.startsWith(\"/\") ? \"\" : \"/\") + url;\n};\n\nexport const redirectWithBasePath = (\n config: AuthConfig,\n targetUrl: string,\n): NextResponse =>\n NextResponse.redirect(prependBasePath(targetUrl, config.basePath || \"\"));\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"routeHandler.d.ts","sourceRoot":"","sources":["../../src/react-router-7/routeHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIjE,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAmBrB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,GAAE,OAAO,CAAC,UAAU,CAAM;mCAscrD,kBAAkB;mCAsClB,kBAAkB;2CAxd5B,OAAO,KAChB,kBAAkB;6CAwBT,OAAO,KAChB,yBAAyB;IAuF1B;;;OAGG;+BAC8B,kBAAkB;IAqBnD;;;OAGG;kCACiC,kBAAkB;IAuEtD;;;OAGG;gCAC+B,kBAAkB;IA8BpD;;;OAGG;8BAC6B,kBAAkB;IAuClD;;;;;;;OAOG;sCACqC,kBAAkB;IAkC1D;;;OAGG;iCACgC,kBAAkB;IAmCrD;;;OAGG;uBACsB,OAAO;IAgBhC;;;OAGG;2BAC0B,OAAO;;;;;;;EAuGvC"}
1
+ {"version":3,"file":"routeHandler.d.ts","sourceRoot":"","sources":["../../src/react-router-7/routeHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIjE,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAmBrB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,GAAE,OAAO,CAAC,UAAU,CAAM;6BAsc3D,MAAM,kBAAkB;6BAsCxB,MAAM,kBAAkB;2CAxd5B,OAAO,KAChB,kBAAkB;6CAwBT,OAAO,KAChB,yBAAyB;IAuF1B;;;OAGG;+BAC8B,kBAAkB;IAqBnD;;;OAGG;kCACiC,kBAAkB;IAuEtD;;;OAGG;gCAC+B,kBAAkB;IA8BpD;;;OAGG;8BAC6B,kBAAkB;IAuClD;;;;;;;OAOG;sCACqC,kBAAkB;IAkC1D;;;OAGG;iCACgC,kBAAkB;IAmCrD;;;OAGG;uBACsB,OAAO;IAgBhC;;;OAGG;2BAC0B,OAAO;;;;;;;EAuGvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonContentOrLoader.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/ButtonContentOrLoader.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG1D;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,8DAK/B;IACD,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qDAiDA,CAAC"}
1
+ {"version":3,"file":"ButtonContentOrLoader.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/ButtonContentOrLoader.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG1D;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,2DAKnC;IACD,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qDAiDA,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SignInButton.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/SignInButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAOxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,UAAU,iBAAiB;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAChD;AAED,QAAA,MAAM,YAAY,gQAWf,iBAAiB,qDAiHnB,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"SignInButton.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/SignInButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAOxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,UAAU,iBAAiB;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAChD;AAED,QAAA,MAAM,YAAY,GAAI,6PAWnB,iBAAiB,qDAiHnB,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SignOutButton.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/SignOutButton.tsx"],"names":[],"mappings":"AACA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAQxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACnC;AAED,QAAA,MAAM,aAAa,oDAMhB,kBAAkB,qDAsEpB,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"SignOutButton.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/SignOutButton.tsx"],"names":[],"mappings":"AACA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAQxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACnC;AAED,QAAA,MAAM,aAAa,GAAI,iDAMpB,kBAAkB,qDAsEpB,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"UserButton.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/UserButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAc,EAKZ,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AA6ChF,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,mBAAmB,CAAC,EAAE,aAAa,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACnC;AAED,QAAA,MAAM,UAAU,4IAab,eAAe,qDAuPjB,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"UserButton.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/UserButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAc,EAKZ,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AA6ChF,UAAU,eAAe;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,mBAAmB,CAAC,EAAE,aAAa,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;CACnC;AAED,QAAA,MAAM,UAAU,GAAI,yIAajB,eAAe,qDAuPjB,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,eACf,UAAU,eACT,WAAW,sBACJ,OAAO,wBAe5B,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/reactjs/components/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAC3B,YAAY,UAAU,EACtB,aAAa,WAAW,EACxB,oBAAoB,OAAO,wBAe5B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useToken.d.ts","sourceRoot":"","sources":["../../../src/reactjs/hooks/useToken.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,QAAQ,YAAa,YAAY,KAAG,gBAuBzC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"useToken.d.ts","sourceRoot":"","sources":["../../../src/reactjs/hooks/useToken.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,QAAQ,GAAI,SAAS,YAAY,KAAG,gBAuBzC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useUser.d.ts","sourceRoot":"","sources":["../../../src/reactjs/hooks/useUser.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAOxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAYjD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE;QACnB,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;KAC1B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,eAAe,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAEzD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD,yBAAyB,EAAE,MAAM,OAAO,CAAC;IACzC,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,iBAAiB,EAAE,MAAM,OAAO,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,QAAA,MAAM,OAAO,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mCACvC,YAAY,KACpB,eAAe,CAAC,CAAC,CA4OnB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"useUser.d.ts","sourceRoot":"","sources":["../../../src/reactjs/hooks/useUser.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAOxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAYjD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE;QACnB,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;KAC1B,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,MAAM,WAAW,eAAe,CAC9B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAEzD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAElD,yBAAyB,EAAE,MAAM,OAAO,CAAC;IACzC,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,iBAAiB,EAAE,MAAM,OAAO,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,QAAA,MAAM,OAAO,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACxE,SAAS,YAAY,KACpB,eAAe,CAAC,CAAC,CA4OnB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../../src/reactjs/styles/colors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,WAAW;;;;;;;;;;;CAWvB,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;CAWtB,CAAC;AAEF,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;CAGlB,CAAC;AAGF,eAAO,MAAM,mBAAmB,oBACd,MAAM,WA0CvB,CAAC;AAGF,eAAO,MAAM,eAAe,WAAW,OAAO,GAAG,MAAM,2BAStD,CAAC"}
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../../src/reactjs/styles/colors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,WAAW;;;;;;;;;;;CAWvB,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;;;;;;;CAWtB,CAAC;AAEF,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;CAGlB,CAAC;AAGF,eAAO,MAAM,mBAAmB,GAC9B,iBAAgB,MAA0B,WA0C3C,CAAC;AAGF,eAAO,MAAM,eAAe,GAAI,QAAO,OAAO,GAAG,MAAgB,2BAShE,CAAC"}
@@ -1,4 +1,15 @@
1
1
  import type { Endpoints } from "../types.ts";
2
+ /**
3
+ * Controls how deep links (original URLs) are handled after authentication.
4
+ *
5
+ * - `"fullUrl"`: Redirect to the original URL the user tried to access.
6
+ * `loginSuccessUrl` is used as fallback only when no deep link exists.
7
+ * - `"queryParamsOnly"`: Redirect to `loginSuccessUrl`, but merge query params from original URL.
8
+ * - `"disabled"`: No deep link preservation. Always use `loginSuccessUrl`.
9
+ *
10
+ * @default "fullUrl"
11
+ */
12
+ export type DeepLinkHandling = "fullUrl" | "queryParamsOnly" | "disabled";
2
13
  /**
3
14
  * Configuration for backend authentication endpoints
4
15
  * Allows customization of API endpoints when using backend integration (loginUrl)
@@ -64,6 +75,18 @@ export type AuthConfig = {
64
75
  * Useful for applications that want to handle token lifecycle manually.
65
76
  */
66
77
  disableRefresh?: boolean;
78
+ /**
79
+ * Optional base path for URL handling.
80
+ * When set, this will be prepended to relative URLs in handleCallback responses.
81
+ * Commonly used with NextJS basePath configuration.
82
+ */
83
+ basePath?: string;
84
+ /**
85
+ * Controls how deep links (original URLs) are handled after authentication.
86
+ * @see DeepLinkHandling
87
+ * @default "fullUrl"
88
+ */
89
+ deepLinkHandling?: DeepLinkHandling;
67
90
  } & ({
68
91
  /** OAuth client ID - required for standard OAuth flow */
69
92
  clientId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACnD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;QACrC,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3B,CAAC;IACF;;OAEG;IACH,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,CACA;IACE,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACD;IACE,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,QAAQ,EAAE,MAAM,CAAC;CAClB,CACJ,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,iBAAiB,GAAG,UAAU,CAAC;AAE1E;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IACnD,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;QACrC,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;KAC3B,CAAC;IACF;;OAEG;IACH,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC,GAAG,CACA;IACE,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACD;IACE,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,QAAQ,EAAE,MAAM,CAAC;CAClB,CACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"","sourcesContent":["import type { Endpoints } from \"@/types.ts\";\n\n/**\n * Configuration for backend authentication endpoints\n * Allows customization of API endpoints when using backend integration (loginUrl)\n */\nexport interface BackendEndpoints {\n /** Endpoint for token refresh (default: \"/auth/refresh\") */\n refresh?: string;\n /** Endpoint for logout (default: \"/auth/logout\") */\n logout?: string;\n /** Endpoint for user info and session validation (default: \"/auth/user\") */\n user?: string;\n /** Endpoint for clearing session/cookies server-side (default: \"/auth/clearsession\") */\n clearSession?: string;\n}\n\nexport type AuthConfig = {\n clientSecret?: string; // Optional client secret for confidential clients\n pkce?: boolean; // Optional PKCE flag, defaults to true if not specified\n redirectUrl: string;\n oauthServer?: string;\n oauthServerBaseUrl?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n endpointOverrides?: Partial<Endpoints> | undefined;\n postLogoutRedirectUrl?: string;\n /**\n * Custom backend endpoints configuration for backend integration\n * Only used when loginUrl is provided. Allows overriding default endpoints.\n */\n backendEndpoints?: BackendEndpoints;\n /**\n * Optional URL to redirect frontend clients back to after successful authentication.\n * When provided, the backend will automatically redirect SPA clients to this URL\n * instead of traditional server-side redirects. Useful for backend + frontend integration.\n * Example: \"http://localhost:5173\" or \"https://your-spa.com\"\n */\n loginSuccessUrl?: string;\n /**\n * Optional CORS configuration for authentication endpoints\n */\n cors?: {\n origin?: string | string[] | boolean;\n credentials?: boolean;\n optionsSuccessStatus?: number;\n allowedHeaders?: string[];\n exposedHeaders?: string[];\n };\n /**\n * Optional logger configuration for authentication middleware\n */\n logger?: {\n enabled?: boolean; // Defaults to true if not specified\n };\n /**\n * Optional flag to disable iframe detection in handleCallback.\n * When true, callbacks will always attempt to redirect instead of returning HTML content for iframes.\n * Useful for testing environments like Cypress where iframe detection may interfere with expected redirects.\n */\n disableIframeDetection?: boolean;\n /**\n * Optional flag to disable automatic token refresh functionality.\n * When true, the SDK will not attempt to refresh expired tokens automatically.\n * This affects both server-side session validation and client-side auto-refresh.\n * Useful for applications that want to handle token lifecycle manually.\n */\n disableRefresh?: boolean;\n} & (\n | {\n /** OAuth client ID - required for standard OAuth flow */\n clientId: string;\n /** Custom login URL for backend integration - optional */\n loginUrl?: string;\n }\n | {\n /** OAuth client ID - optional when using backend integration */\n clientId?: string;\n /** Custom login URL for backend integration - required when clientId is not provided */\n loginUrl: string;\n }\n);\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/server/config.ts"],"names":[],"mappings":"","sourcesContent":["import type { Endpoints } from \"@/types.ts\";\n\n/**\n * Controls how deep links (original URLs) are handled after authentication.\n *\n * - `\"fullUrl\"`: Redirect to the original URL the user tried to access.\n * `loginSuccessUrl` is used as fallback only when no deep link exists.\n * - `\"queryParamsOnly\"`: Redirect to `loginSuccessUrl`, but merge query params from original URL.\n * - `\"disabled\"`: No deep link preservation. Always use `loginSuccessUrl`.\n *\n * @default \"fullUrl\"\n */\nexport type DeepLinkHandling = \"fullUrl\" | \"queryParamsOnly\" | \"disabled\";\n\n/**\n * Configuration for backend authentication endpoints\n * Allows customization of API endpoints when using backend integration (loginUrl)\n */\nexport interface BackendEndpoints {\n /** Endpoint for token refresh (default: \"/auth/refresh\") */\n refresh?: string;\n /** Endpoint for logout (default: \"/auth/logout\") */\n logout?: string;\n /** Endpoint for user info and session validation (default: \"/auth/user\") */\n user?: string;\n /** Endpoint for clearing session/cookies server-side (default: \"/auth/clearsession\") */\n clearSession?: string;\n}\n\nexport type AuthConfig = {\n clientSecret?: string; // Optional client secret for confidential clients\n pkce?: boolean; // Optional PKCE flag, defaults to true if not specified\n redirectUrl: string;\n oauthServer?: string;\n oauthServerBaseUrl?: string;\n challengeUrl?: string;\n refreshUrl?: string;\n endpointOverrides?: Partial<Endpoints> | undefined;\n postLogoutRedirectUrl?: string;\n /**\n * Custom backend endpoints configuration for backend integration\n * Only used when loginUrl is provided. Allows overriding default endpoints.\n */\n backendEndpoints?: BackendEndpoints;\n /**\n * Optional URL to redirect frontend clients back to after successful authentication.\n * When provided, the backend will automatically redirect SPA clients to this URL\n * instead of traditional server-side redirects. Useful for backend + frontend integration.\n * Example: \"http://localhost:5173\" or \"https://your-spa.com\"\n */\n loginSuccessUrl?: string;\n /**\n * Optional CORS configuration for authentication endpoints\n */\n cors?: {\n origin?: string | string[] | boolean;\n credentials?: boolean;\n optionsSuccessStatus?: number;\n allowedHeaders?: string[];\n exposedHeaders?: string[];\n };\n /**\n * Optional logger configuration for authentication middleware\n */\n logger?: {\n enabled?: boolean; // Defaults to true if not specified\n };\n /**\n * Optional flag to disable iframe detection in handleCallback.\n * When true, callbacks will always attempt to redirect instead of returning HTML content for iframes.\n * Useful for testing environments like Cypress where iframe detection may interfere with expected redirects.\n */\n disableIframeDetection?: boolean;\n /**\n * Optional flag to disable automatic token refresh functionality.\n * When true, the SDK will not attempt to refresh expired tokens automatically.\n * This affects both server-side session validation and client-side auto-refresh.\n * Useful for applications that want to handle token lifecycle manually.\n */\n disableRefresh?: boolean;\n /**\n * Optional base path for URL handling.\n * When set, this will be prepended to relative URLs in handleCallback responses.\n * Commonly used with NextJS basePath configuration.\n */\n basePath?: string;\n /**\n * Controls how deep links (original URLs) are handled after authentication.\n * @see DeepLinkHandling\n * @default \"fullUrl\"\n */\n deepLinkHandling?: DeepLinkHandling;\n} & (\n | {\n /** OAuth client ID - required for standard OAuth flow */\n clientId: string;\n /** Custom login URL for backend integration - optional */\n loginUrl?: string;\n }\n | {\n /** OAuth client ID - optional when using backend integration */\n clientId?: string;\n /** Custom login URL for backend integration - required when clientId is not provided */\n loginUrl: string;\n }\n);\n"]}
@@ -91,6 +91,63 @@ export declare class CivicAuth {
91
91
  * Clear all authentication tokens from storage
92
92
  */
93
93
  clearTokens(): Promise<void>;
94
+ /**
95
+ * Handles deep linking by computing the return URL and setting it as a cookie.
96
+ * This method encapsulates the deep-linking logic for use by middleware in any framework.
97
+ *
98
+ * The method automatically detects whether the user is at the login URL or a protected route
99
+ * and applies the appropriate logic:
100
+ *
101
+ * **At login URL:**
102
+ * - Auth redirect (marker present): Preserve existing deep link cookie
103
+ * - Fresh navigation with query params: Set cookie with query params
104
+ * - Fresh navigation without params: Clear stale cookie
105
+ *
106
+ * **At protected route:**
107
+ * - Always set the cookie to capture the deep link destination
108
+ *
109
+ * @param requestUrl - The full URL of the request being made (the page the user tried to access)
110
+ * @param originUrl - The origin URL of the application (e.g., "https://myapp.com")
111
+ * @returns The computed deep link destination, or null if deep linking is disabled or the URL is invalid
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * // In middleware for any framework
116
+ * if (!session.authenticated) {
117
+ * await civicAuth.handleDeepLinking(requestUrl, originUrl);
118
+ * }
119
+ * ```
120
+ */
121
+ handleDeepLinking(requestUrl: string, originUrl: string): Promise<string | null>;
122
+ /**
123
+ * Internal: Handles deep linking when at a protected route.
124
+ * Sets the cookie to capture the user's intended destination and the auth redirect marker.
125
+ */
126
+ private handleDeepLinkingAtProtectedRoute;
127
+ /**
128
+ * Internal: Handles deep linking when at the login URL.
129
+ * Checks the auth redirect marker and handles appropriately.
130
+ */
131
+ private handleDeepLinkingAtLoginUrl;
132
+ /**
133
+ * Sets the auth redirect marker cookie. This marker helps distinguish auth redirects
134
+ * from fresh navigations to the login page, preventing the deep link cookie from being
135
+ * incorrectly overwritten.
136
+ *
137
+ * **Note:** This method is automatically called by `handleDeepLinking` when the user is
138
+ * at a protected route. You typically do NOT need to call this method manually unless
139
+ * you have a specific use case where you're not using `handleDeepLinking`.
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * // In most cases, just call handleDeepLinking - it sets the marker automatically:
144
+ * if (!isAuthenticated) {
145
+ * await req.civicAuth.handleDeepLinking(requestUrl, originUrl);
146
+ * return res.redirect('/login');
147
+ * }
148
+ * ```
149
+ */
150
+ setAuthRedirectMarker(): Promise<void>;
94
151
  /**
95
152
  * Framework-agnostic URL detection and resolution helpers
96
153
  * These methods handle proxy environments and can be used by any framework
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/server/session.ts"],"names":[],"mappings":"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"}