@tern-secure/nextjs 5.2.0-canary.v20250916132854 → 5.2.0-canary.v20250919131424

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 (76) hide show
  1. package/dist/cjs/app-router/admin/api/endpoints/abstract.js +39 -0
  2. package/dist/cjs/app-router/admin/api/endpoints/abstract.js.map +1 -0
  3. package/dist/cjs/app-router/admin/api/endpoints/sessions.js +2 -0
  4. package/dist/cjs/app-router/admin/api/endpoints/sessions.js.map +1 -0
  5. package/dist/cjs/app-router/admin/api/endpoints/users.js +4 -0
  6. package/dist/cjs/app-router/admin/api/endpoints/users.js.map +1 -0
  7. package/dist/cjs/app-router/admin/claude-authenticateRequestProcessor.js +79 -0
  8. package/dist/cjs/app-router/admin/claude-authenticateRequestProcessor.js.map +1 -0
  9. package/dist/cjs/app-router/admin/endpointRouter.js +72 -0
  10. package/dist/cjs/app-router/admin/endpointRouter.js.map +1 -0
  11. package/dist/cjs/app-router/admin/fnValidators.js +4 -3
  12. package/dist/cjs/app-router/admin/fnValidators.js.map +1 -1
  13. package/dist/cjs/app-router/admin/handlerUtils.js +63 -0
  14. package/dist/cjs/app-router/admin/handlerUtils.js.map +1 -0
  15. package/dist/cjs/app-router/admin/index.js +8 -0
  16. package/dist/cjs/app-router/admin/index.js.map +1 -1
  17. package/dist/cjs/app-router/admin/sessionHandlers.js +15 -13
  18. package/dist/cjs/app-router/admin/sessionHandlers.js.map +1 -1
  19. package/dist/cjs/app-router/admin/ternsecureNextjsHandler.js +31 -36
  20. package/dist/cjs/app-router/admin/ternsecureNextjsHandler.js.map +1 -1
  21. package/dist/cjs/app-router/admin/types.js +0 -1
  22. package/dist/cjs/app-router/admin/types.js.map +1 -1
  23. package/dist/cjs/app-router/admin/validators.js +1 -2
  24. package/dist/cjs/app-router/admin/validators.js.map +1 -1
  25. package/dist/cjs/utils/NextCookieAdapter.js.map +1 -1
  26. package/dist/esm/app-router/admin/api/endpoints/abstract.js +15 -0
  27. package/dist/esm/app-router/admin/api/endpoints/abstract.js.map +1 -0
  28. package/dist/esm/app-router/admin/api/endpoints/sessions.js +1 -0
  29. package/dist/esm/app-router/admin/api/endpoints/sessions.js.map +1 -0
  30. package/dist/esm/app-router/admin/api/endpoints/users.js +3 -0
  31. package/dist/esm/app-router/admin/api/endpoints/users.js.map +1 -0
  32. package/dist/esm/app-router/admin/claude-authenticateRequestProcessor.js +55 -0
  33. package/dist/esm/app-router/admin/claude-authenticateRequestProcessor.js.map +1 -0
  34. package/dist/esm/app-router/admin/endpointRouter.js +48 -0
  35. package/dist/esm/app-router/admin/endpointRouter.js.map +1 -0
  36. package/dist/esm/app-router/admin/fnValidators.js +4 -3
  37. package/dist/esm/app-router/admin/fnValidators.js.map +1 -1
  38. package/dist/esm/app-router/admin/handlerUtils.js +38 -0
  39. package/dist/esm/app-router/admin/handlerUtils.js.map +1 -0
  40. package/dist/esm/app-router/admin/index.js +5 -0
  41. package/dist/esm/app-router/admin/index.js.map +1 -1
  42. package/dist/esm/app-router/admin/sessionHandlers.js +15 -13
  43. package/dist/esm/app-router/admin/sessionHandlers.js.map +1 -1
  44. package/dist/esm/app-router/admin/ternsecureNextjsHandler.js +34 -41
  45. package/dist/esm/app-router/admin/ternsecureNextjsHandler.js.map +1 -1
  46. package/dist/esm/app-router/admin/types.js +0 -1
  47. package/dist/esm/app-router/admin/types.js.map +1 -1
  48. package/dist/esm/app-router/admin/validators.js +1 -2
  49. package/dist/esm/app-router/admin/validators.js.map +1 -1
  50. package/dist/esm/utils/NextCookieAdapter.js.map +1 -1
  51. package/dist/types/app-router/admin/api/endpoints/abstract.d.ts +19 -0
  52. package/dist/types/app-router/admin/api/endpoints/abstract.d.ts.map +1 -0
  53. package/dist/types/app-router/admin/api/endpoints/sessions.d.ts +2 -0
  54. package/dist/types/app-router/admin/api/endpoints/sessions.d.ts.map +1 -0
  55. package/dist/types/app-router/admin/api/endpoints/users.d.ts +2 -0
  56. package/dist/types/app-router/admin/api/endpoints/users.d.ts.map +1 -0
  57. package/dist/types/app-router/admin/claude-authenticateRequestProcessor.d.ts +37 -0
  58. package/dist/types/app-router/admin/claude-authenticateRequestProcessor.d.ts.map +1 -0
  59. package/dist/types/app-router/admin/endpointRouter.d.ts +10 -0
  60. package/dist/types/app-router/admin/endpointRouter.d.ts.map +1 -0
  61. package/dist/types/app-router/admin/fnValidators.d.ts +11 -12
  62. package/dist/types/app-router/admin/fnValidators.d.ts.map +1 -1
  63. package/dist/types/app-router/admin/handlerUtils.d.ts +19 -0
  64. package/dist/types/app-router/admin/handlerUtils.d.ts.map +1 -0
  65. package/dist/types/app-router/admin/index.d.ts +4 -1
  66. package/dist/types/app-router/admin/index.d.ts.map +1 -1
  67. package/dist/types/app-router/admin/sessionHandlers.d.ts +3 -4
  68. package/dist/types/app-router/admin/sessionHandlers.d.ts.map +1 -1
  69. package/dist/types/app-router/admin/ternsecureNextjsHandler.d.ts +3 -4
  70. package/dist/types/app-router/admin/ternsecureNextjsHandler.d.ts.map +1 -1
  71. package/dist/types/app-router/admin/types.d.ts +2 -3
  72. package/dist/types/app-router/admin/types.d.ts.map +1 -1
  73. package/dist/types/app-router/admin/validators.d.ts +10 -12
  74. package/dist/types/app-router/admin/validators.d.ts.map +1 -1
  75. package/dist/types/utils/NextCookieAdapter.d.ts.map +1 -1
  76. package/package.json +5 -5
@@ -1,25 +1,27 @@
1
1
  import { clearSessionCookie, createSessionCookie } from "@tern-secure/backend/admin";
2
2
  import { ternDecodeJwtUnguarded } from "@tern-secure/backend/jwt";
3
+ import { cookies } from "next/headers";
3
4
  import { NextCookieStore } from "../../utils/NextCookieAdapter";
4
5
  import { createApiErrorResponse, HttpResponseHelper, SessionResponseHelper } from "./responses";
5
6
  import { CsrfValidator, RequestValidator } from "./validators";
6
7
  class SessionGetHandler {
7
- static async handle(request, subEndpoint, _config) {
8
+ static async handle(subEndpoint, _config) {
8
9
  switch (subEndpoint) {
9
10
  case "verify":
10
- return this.handleVerify(request);
11
+ return this.handleVerify();
11
12
  default:
12
13
  return HttpResponseHelper.createNotFoundResponse();
13
14
  }
14
15
  }
15
- static async handleVerify(request) {
16
+ static async handleVerify() {
16
17
  try {
17
- const sessionCookie = request.cookies.get("_session_cookie")?.value;
18
+ const cookieStore = await cookies();
19
+ const sessionCookie = cookieStore.get("_session_cookie")?.value;
18
20
  if (!sessionCookie) {
19
21
  return SessionResponseHelper.createUnauthorizedResponse();
20
22
  }
21
- const decodedSession = ternDecodeJwtUnguarded(sessionCookie);
22
- if (decodedSession.errors) {
23
+ const { data: decodedSession, errors } = ternDecodeJwtUnguarded(sessionCookie);
24
+ if (errors) {
23
25
  return SessionResponseHelper.createUnauthorizedResponse();
24
26
  }
25
27
  return SessionResponseHelper.createVerificationResponse(decodedSession);
@@ -33,8 +35,8 @@ class SessionPostHandler {
33
35
  const cookieStore = new NextCookieStore();
34
36
  const { idToken, csrfToken, error } = await RequestValidator.validateSessionRequest(request);
35
37
  if (error) return error;
36
- const csrfCookieValue = request.cookies.get("_session_terncf")?.value;
37
- const csrfValidationError = CsrfValidator.validate(csrfToken || "", csrfCookieValue);
38
+ const csrfCookieValue = await cookieStore.get("_session_terncf");
39
+ const csrfValidationError = CsrfValidator.validate(csrfToken || "", csrfCookieValue.value);
38
40
  if (csrfValidationError) return csrfValidationError;
39
41
  const options = {
40
42
  tenantId: _config.tenantId
@@ -43,7 +45,7 @@ class SessionPostHandler {
43
45
  case "createsession":
44
46
  return this.handleCreateSession(options, idToken, cookieStore);
45
47
  case "refresh":
46
- return this.handleRefreshSession(request, cookieStore);
48
+ return this.handleRefreshSession(cookieStore);
47
49
  case "revoke":
48
50
  return this.handleRevokeSession(cookieStore);
49
51
  default:
@@ -63,13 +65,13 @@ class SessionPostHandler {
63
65
  return createApiErrorResponse("SESSION_CREATION_FAILED", "Session creation failed", 500);
64
66
  }
65
67
  }
66
- static async handleRefreshSession(request, cookieStore) {
67
- const currentSessionCookie = request.cookies.get("__session")?.value;
68
+ static async handleRefreshSession(cookieStore) {
69
+ const currentSessionCookie = await cookieStore.get("__session");
68
70
  if (!currentSessionCookie) {
69
71
  return createApiErrorResponse("NO_SESSION", "No session to refresh", 401);
70
72
  }
71
73
  try {
72
- const decodedSession = ternDecodeJwtUnguarded(currentSessionCookie);
74
+ const decodedSession = ternDecodeJwtUnguarded(currentSessionCookie.value || "");
73
75
  if (decodedSession.errors) {
74
76
  return createApiErrorResponse("INVALID_SESSION", "Invalid session for refresh", 401);
75
77
  }
@@ -103,7 +105,7 @@ class SessionEndpointHandler {
103
105
  }
104
106
  switch (method) {
105
107
  case "GET":
106
- return SessionGetHandler.handle(request, subEndpoint, config);
108
+ return SessionGetHandler.handle(subEndpoint, config);
107
109
  case "POST":
108
110
  return SessionPostHandler.handle(request, subEndpoint, config);
109
111
  default:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/sessionHandlers.ts"],"sourcesContent":["import type { RequestOptions } from '@tern-secure/backend';\nimport { clearSessionCookie, createSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded } from '@tern-secure/backend/jwt';\nimport type { NextRequest, NextResponse } from 'next/server';\n\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { createApiErrorResponse, HttpResponseHelper, SessionResponseHelper } from './responses';\nimport type {\n SessionSubEndpoint,\n TernSecureHandlerOptions,\n TernSecureInternalHandlerConfig,\n} from './types';\nimport { CsrfValidator, RequestValidator } from './validators';\n\n/**\n * Session GET request handlers\n */\nexport class SessionGetHandler {\n static async handle(\n request: NextRequest,\n subEndpoint: SessionSubEndpoint,\n _config: Required<TernSecureHandlerOptions>,\n ): Promise<NextResponse> {\n switch (subEndpoint) {\n case 'verify':\n return this.handleVerify(request);\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n }\n\n private static async handleVerify(request: NextRequest): Promise<NextResponse> {\n try {\n const sessionCookie = request.cookies.get('_session_cookie')?.value;\n if (!sessionCookie) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n const decodedSession = ternDecodeJwtUnguarded(sessionCookie);\n if (decodedSession.errors) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n return SessionResponseHelper.createVerificationResponse(decodedSession);\n } catch (error) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n }\n}\n\n/**\n * Session POST request handlers\n */\nexport class SessionPostHandler {\n static async handle(\n request: NextRequest,\n subEndpoint: SessionSubEndpoint,\n _config: TernSecureInternalHandlerConfig,\n ): Promise<NextResponse> {\n const cookieStore = new NextCookieStore();\n\n const { idToken, csrfToken, error } = await RequestValidator.validateSessionRequest(request);\n if (error) return error;\n\n const csrfCookieValue = request.cookies.get('_session_terncf')?.value;\n const csrfValidationError = CsrfValidator.validate(csrfToken || '', csrfCookieValue);\n if (csrfValidationError) return csrfValidationError;\n\n const options = {\n tenantId: _config.tenantId,\n };\n\n switch (subEndpoint) {\n case 'createsession':\n return this.handleCreateSession(options, idToken, cookieStore);\n case 'refresh':\n return this.handleRefreshSession(request, cookieStore);\n case 'revoke':\n return this.handleRevokeSession(cookieStore);\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n }\n\n private static async handleCreateSession(\n options: RequestOptions,\n idToken: string | undefined,\n cookieStore: NextCookieStore,\n ): Promise<NextResponse> {\n const validationError = RequestValidator.validateIdToken(idToken);\n if (validationError) return validationError;\n if (!idToken) {\n return createApiErrorResponse('ID_TOKEN_REQUIRED', 'ID token is required', 400);\n }\n\n try {\n const res = await createSessionCookie(idToken, cookieStore, options);\n return SessionResponseHelper.createSessionCreationResponse(res);\n } catch (error) {\n return createApiErrorResponse('SESSION_CREATION_FAILED', 'Session creation failed', 500);\n }\n }\n\n private static async handleRefreshSession(\n request: NextRequest,\n cookieStore: NextCookieStore,\n ): Promise<NextResponse> {\n const currentSessionCookie = request.cookies.get('__session')?.value;\n if (!currentSessionCookie) {\n return createApiErrorResponse('NO_SESSION', 'No session to refresh', 401);\n }\n\n try {\n const decodedSession = ternDecodeJwtUnguarded(currentSessionCookie);\n if (decodedSession.errors) {\n return createApiErrorResponse('INVALID_SESSION', 'Invalid session for refresh', 401);\n }\n\n const refreshRes = await createSessionCookie(\n decodedSession.data?.payload?.sub || '',\n cookieStore,\n );\n\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n return createApiErrorResponse('REFRESH_FAILED', 'Session refresh failed', 500);\n }\n }\n\n private static async handleRevokeSession(cookieStore: NextCookieStore): Promise<NextResponse> {\n const res = await clearSessionCookie(cookieStore);\n return SessionResponseHelper.createRevokeResponse(res);\n }\n}\n\n/**\n * Main session endpoint orchestrator\n */\nexport class SessionEndpointHandler {\n static async handle(\n request: NextRequest,\n method: string,\n subEndpoint: SessionSubEndpoint | undefined,\n config: Required<TernSecureHandlerOptions>,\n ): Promise<NextResponse> {\n const sessionsConfig = config.endpoints.sessions;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n const subEndpointConfig = sessionsConfig?.subEndpoints?.[subEndpoint];\n\n const subEndpointValidation = this.validateSubEndpoint(subEndpoint, subEndpointConfig, method);\n if (subEndpointValidation) return subEndpointValidation;\n\n if (subEndpointConfig?.security) {\n const { SecurityValidator } = await import('./validators.js');\n const securityResult = await SecurityValidator.validate(request, subEndpointConfig.security);\n if (securityResult) return securityResult;\n }\n\n switch (method) {\n case 'GET':\n return SessionGetHandler.handle(request, subEndpoint, config);\n case 'POST':\n return SessionPostHandler.handle(request, subEndpoint, config);\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n }\n\n private static validateSubEndpoint(\n subEndpoint: SessionSubEndpoint | undefined,\n subEndpointConfig: any,\n method: string,\n ): NextResponse | null {\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (!subEndpointConfig.methods?.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/sessionHandlers.ts"],"sourcesContent":["import type { RequestOptions } from '@tern-secure/backend';\nimport { clearSessionCookie, createSessionCookie } from '@tern-secure/backend/admin';\nimport { ternDecodeJwtUnguarded} from '@tern-secure/backend/jwt';\nimport { cookies } from 'next/headers';\n\nimport { NextCookieStore } from '../../utils/NextCookieAdapter';\nimport { createApiErrorResponse, HttpResponseHelper, SessionResponseHelper } from './responses';\nimport type {\n SessionSubEndpoint,\n TernSecureHandlerOptions,\n TernSecureInternalHandlerConfig,\n} from './types';\nimport { CsrfValidator, RequestValidator } from './validators';\n\n/**\n * Session GET request handlers\n */\nexport class SessionGetHandler {\n static async handle(\n subEndpoint: SessionSubEndpoint,\n _config: Required<TernSecureHandlerOptions>,\n ): Promise<Response> {\n switch (subEndpoint) {\n case 'verify':\n return this.handleVerify();\n default:\n return HttpResponseHelper.createNotFoundResponse();\n }\n }\n\n private static async handleVerify(): Promise<Response> {\n try {\n const cookieStore = await cookies();\n const sessionCookie = cookieStore.get('_session_cookie')?.value;\n if (!sessionCookie) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n const { data: decodedSession, errors } = ternDecodeJwtUnguarded(sessionCookie);\n if (errors) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n\n return SessionResponseHelper.createVerificationResponse(decodedSession);\n } catch (error) {\n return SessionResponseHelper.createUnauthorizedResponse();\n }\n }\n}\n\n/**\n * Session POST request handlers\n */\nexport class SessionPostHandler {\n static async handle(\n request: Request,\n subEndpoint: SessionSubEndpoint,\n _config: TernSecureInternalHandlerConfig,\n ): Promise<Response> {\n const cookieStore = new NextCookieStore();\n\n const { idToken, csrfToken, error } = await RequestValidator.validateSessionRequest(request);\n if (error) return error;\n\n const csrfCookieValue = await cookieStore.get('_session_terncf');\n const csrfValidationError = CsrfValidator.validate(csrfToken || '', csrfCookieValue.value);\n if (csrfValidationError) return csrfValidationError;\n\n const options = {\n tenantId: _config.tenantId,\n };\n\n switch (subEndpoint) {\n case 'createsession':\n return this.handleCreateSession(options, idToken, cookieStore);\n case 'refresh':\n return this.handleRefreshSession(cookieStore);\n case 'revoke':\n return this.handleRevokeSession(cookieStore);\n default:\n return HttpResponseHelper.createSubEndpointNotSupportedResponse();\n }\n }\n\n private static async handleCreateSession(\n options: RequestOptions,\n idToken: string | undefined,\n cookieStore: NextCookieStore,\n ): Promise<Response> {\n const validationError = RequestValidator.validateIdToken(idToken);\n if (validationError) return validationError;\n if (!idToken) {\n return createApiErrorResponse('ID_TOKEN_REQUIRED', 'ID token is required', 400);\n }\n\n try {\n const res = await createSessionCookie(idToken, cookieStore, options);\n return SessionResponseHelper.createSessionCreationResponse(res);\n } catch (error) {\n return createApiErrorResponse('SESSION_CREATION_FAILED', 'Session creation failed', 500);\n }\n }\n\n private static async handleRefreshSession(\n cookieStore: NextCookieStore,\n ): Promise<Response> {\n const currentSessionCookie = await cookieStore.get('__session');\n if (!currentSessionCookie) {\n return createApiErrorResponse('NO_SESSION', 'No session to refresh', 401);\n }\n\n try {\n const decodedSession = ternDecodeJwtUnguarded(currentSessionCookie.value || '');\n if (decodedSession.errors) {\n return createApiErrorResponse('INVALID_SESSION', 'Invalid session for refresh', 401);\n }\n\n const refreshRes = await createSessionCookie(\n decodedSession.data?.payload?.sub || '',\n cookieStore,\n );\n\n return SessionResponseHelper.createRefreshResponse(refreshRes);\n } catch (error) {\n return createApiErrorResponse('REFRESH_FAILED', 'Session refresh failed', 500);\n }\n }\n\n private static async handleRevokeSession(cookieStore: NextCookieStore): Promise<Response> {\n const res = await clearSessionCookie(cookieStore);\n return SessionResponseHelper.createRevokeResponse(res);\n }\n}\n\n/**\n * Main session endpoint orchestrator\n */\nexport class SessionEndpointHandler {\n static async handle(\n request: Request,\n method: string,\n subEndpoint: SessionSubEndpoint | undefined,\n config: Required<TernSecureHandlerOptions>,\n ): Promise<Response> {\n const sessionsConfig = config.endpoints.sessions;\n\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n const subEndpointConfig = sessionsConfig?.subEndpoints?.[subEndpoint];\n\n const subEndpointValidation = this.validateSubEndpoint(subEndpoint, subEndpointConfig, method);\n if (subEndpointValidation) return subEndpointValidation;\n\n if (subEndpointConfig?.security) {\n const { SecurityValidator } = await import('./validators.js');\n const securityResult = await SecurityValidator.validate(request, subEndpointConfig.security);\n if (securityResult) return securityResult;\n }\n\n switch (method) {\n case 'GET':\n return SessionGetHandler.handle(subEndpoint, config);\n case 'POST':\n return SessionPostHandler.handle(request, subEndpoint, config);\n default:\n return HttpResponseHelper.createMethodNotAllowedResponse();\n }\n }\n\n private static validateSubEndpoint(\n subEndpoint: SessionSubEndpoint | undefined,\n subEndpointConfig: any,\n method: string,\n ): Response | null {\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (!subEndpointConfig.methods?.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,56 +1,49 @@
1
1
  import { TENANT_ID } from "./constants";
2
- import { createRequestContext, createValidators } from "./fnValidators";
2
+ import { EndpointRouter } from "./endpointRouter";
3
+ import { createRequestContext } from "./fnValidators";
4
+ import { RequestContextBuilder, ValidationPipeline } from "./handlerUtils";
3
5
  import { createApiErrorResponse } from "./responses";
4
- import { SessionEndpointHandler } from "./sessionHandlers";
5
- import {
6
- DEFAULT_HANDLER_OPTIONS
7
- } from "./types";
8
- import { ConfigUtils, LoggingUtils } from "./utils";
9
- async function applyGlobalValidations(config, context) {
10
- const { validateCors, validateSecurity, createCorsOptionsResponse } = createValidators(context);
11
- const corsError = await validateCors(config.cors);
12
- if (corsError) return corsError;
13
- if (context.method === "OPTIONS") {
14
- return createCorsOptionsResponse(config.cors);
6
+ import { DEFAULT_HANDLER_OPTIONS } from "./types";
7
+ import { ConfigUtils } from "./utils";
8
+ class HandlerConfigFactory {
9
+ static create(options) {
10
+ const baseConfig = ConfigUtils.mergeWithDefaults(
11
+ DEFAULT_HANDLER_OPTIONS,
12
+ options
13
+ );
14
+ return {
15
+ ...baseConfig,
16
+ tenantId: TENANT_ID
17
+ };
15
18
  }
16
- const securityError = await validateSecurity(config.security);
17
- if (securityError) return securityError;
18
- return null;
19
19
  }
20
- async function routeToEndpointHandler(request, endpoint, subEndpoint, config) {
21
- switch (endpoint) {
22
- case "sessions":
23
- return SessionEndpointHandler.handle(request, request.method, subEndpoint, config);
24
- default:
25
- return createApiErrorResponse("ENDPOINT_NOT_FOUND", "Endpoint not found", 404);
20
+ class TernSecureRequestHandler {
21
+ config;
22
+ constructor(config) {
23
+ this.config = config;
26
24
  }
27
- }
28
- function createTernSecureNextJsHandler(options) {
29
- const baseConfig = ConfigUtils.mergeWithDefaults(
30
- DEFAULT_HANDLER_OPTIONS,
31
- options
32
- );
33
- const internalConfig = {
34
- ...baseConfig,
35
- tenantId: TENANT_ID
36
- };
37
- const handler = async (request) => {
38
- const context = createRequestContext(request);
39
- const { pathSegments } = context;
40
- const endpoint = pathSegments[2];
41
- const subEndpoint = pathSegments[3];
42
- LoggingUtils.logRequest(request, "Handler");
25
+ async handle(request) {
26
+ const handlerContext = RequestContextBuilder.create(request);
27
+ const validationContext = createRequestContext(request);
43
28
  try {
44
- const validationResult = await applyGlobalValidations(internalConfig, context);
29
+ const validationResult = await this.executeValidation(validationContext);
45
30
  if (validationResult) {
46
31
  return validationResult;
47
32
  }
48
- return await routeToEndpointHandler(request, endpoint, subEndpoint, internalConfig);
33
+ return await EndpointRouter.route(handlerContext, this.config);
49
34
  } catch (error) {
50
- LoggingUtils.logError(error, "Handler");
51
35
  return createApiErrorResponse("INTERNAL_SERVER_ERROR", "Internal server error", 500);
52
36
  }
53
- };
37
+ }
38
+ async executeValidation(validationContext) {
39
+ const validationPipeline = new ValidationPipeline(this.config, validationContext);
40
+ return validationPipeline.execute();
41
+ }
42
+ }
43
+ function createTernSecureNextJsHandler(options) {
44
+ const config = HandlerConfigFactory.create(options);
45
+ const requestHandler = new TernSecureRequestHandler(config);
46
+ const handler = async (request) => await requestHandler.handle(request);
54
47
  return {
55
48
  GET: handler,
56
49
  POST: handler
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/ternsecureNextjsHandler.ts"],"sourcesContent":["import type { NextRequest, NextResponse } from 'next/server';\n\nimport { TENANT_ID } from './constants';\nimport type { RequestContext } from './fnValidators';\nimport { createRequestContext, createValidators } from './fnValidators';\nimport { createApiErrorResponse } from './responses';\nimport { SessionEndpointHandler } from './sessionHandlers';\nimport type {\n AuthEndpoint,\n SessionSubEndpoint,\n TernSecureHandlerOptions,\n TernSecureInternalHandlerConfig} from './types';\nimport {\n DEFAULT_HANDLER_OPTIONS\n} from './types';\nimport { ConfigUtils, LoggingUtils } from './utils';\n\n/**\n * Apply all global validations in a clean, sequential manner\n */\nasync function applyGlobalValidations(\n config: Required<TernSecureHandlerOptions>,\n context: RequestContext,\n): Promise<NextResponse | null> {\n const { validateCors, validateSecurity, createCorsOptionsResponse } = createValidators(context);\n const corsError = await validateCors(config.cors);\n if (corsError) return corsError;\n\n if (context.method === 'OPTIONS') {\n return createCorsOptionsResponse(config.cors);\n }\n\n const securityError = await validateSecurity(config.security);\n if (securityError) return securityError;\n\n return null;\n}\n\n/**\n * Route to appropriate endpoint handler based on endpoint type\n */\nasync function routeToEndpointHandler(\n request: NextRequest,\n endpoint: AuthEndpoint,\n subEndpoint: SessionSubEndpoint,\n config: TernSecureInternalHandlerConfig,\n): Promise<NextResponse> {\n switch (endpoint) {\n case 'sessions':\n return SessionEndpointHandler.handle(request, request.method, subEndpoint, config);\n default:\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n}\n\nexport function createTernSecureNextJsHandler(options?: TernSecureHandlerOptions) {\n const baseConfig: Required<TernSecureHandlerOptions> = ConfigUtils.mergeWithDefaults(\n DEFAULT_HANDLER_OPTIONS,\n options,\n );\n\n const internalConfig: TernSecureInternalHandlerConfig = {\n ...baseConfig,\n tenantId: TENANT_ID,\n };\n\n const handler = async (request: NextRequest): Promise<NextResponse> => {\n const context = createRequestContext(request);\n const { pathSegments } = context;\n\n const endpoint = pathSegments[2] as AuthEndpoint;\n const subEndpoint = pathSegments[3] as SessionSubEndpoint;\n\n LoggingUtils.logRequest(request, 'Handler');\n\n try {\n const validationResult = await applyGlobalValidations(internalConfig, context);\n if (validationResult) {\n return validationResult;\n }\n\n return await routeToEndpointHandler(request, endpoint, subEndpoint, internalConfig);\n } catch (error) {\n LoggingUtils.logError(error, 'Handler');\n return createApiErrorResponse('INTERNAL_SERVER_ERROR', 'Internal server error', 500);\n }\n };\n\n return {\n GET: handler,\n POST: handler,\n };\n}\n"],"mappings":"AAEA,SAAS,iBAAiB;AAE1B,SAAS,sBAAsB,wBAAwB;AACvD,SAAS,8BAA8B;AACvC,SAAS,8BAA8B;AAMvC;AAAA,EACE;AAAA,OACK;AACP,SAAS,aAAa,oBAAoB;AAK1C,eAAe,uBACb,QACA,SAC8B;AAC9B,QAAM,EAAE,cAAc,kBAAkB,0BAA0B,IAAI,iBAAiB,OAAO;AAC9F,QAAM,YAAY,MAAM,aAAa,OAAO,IAAI;AAChD,MAAI,UAAW,QAAO;AAEtB,MAAI,QAAQ,WAAW,WAAW;AAChC,WAAO,0BAA0B,OAAO,IAAI;AAAA,EAC9C;AAEA,QAAM,gBAAgB,MAAM,iBAAiB,OAAO,QAAQ;AAC5D,MAAI,cAAe,QAAO;AAE1B,SAAO;AACT;AAKA,eAAe,uBACb,SACA,UACA,aACA,QACuB;AACvB,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,uBAAuB,OAAO,SAAS,QAAQ,QAAQ,aAAa,MAAM;AAAA,IACnF;AACE,aAAO,uBAAuB,sBAAsB,sBAAsB,GAAG;AAAA,EACjF;AACF;AAEO,SAAS,8BAA8B,SAAoC;AAChF,QAAM,aAAiD,YAAY;AAAA,IACjE;AAAA,IACA;AAAA,EACF;AAEA,QAAM,iBAAkD;AAAA,IACtD,GAAG;AAAA,IACH,UAAU;AAAA,EACZ;AAEA,QAAM,UAAU,OAAO,YAAgD;AACrE,UAAM,UAAU,qBAAqB,OAAO;AAC5C,UAAM,EAAE,aAAa,IAAI;AAEzB,UAAM,WAAW,aAAa,CAAC;AAC/B,UAAM,cAAc,aAAa,CAAC;AAElC,iBAAa,WAAW,SAAS,SAAS;AAE1C,QAAI;AACF,YAAM,mBAAmB,MAAM,uBAAuB,gBAAgB,OAAO;AAC7E,UAAI,kBAAkB;AACpB,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,uBAAuB,SAAS,UAAU,aAAa,cAAc;AAAA,IACpF,SAAS,OAAO;AACd,mBAAa,SAAS,OAAO,SAAS;AACtC,aAAO,uBAAuB,yBAAyB,yBAAyB,GAAG;AAAA,IACrF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/ternsecureNextjsHandler.ts"],"sourcesContent":["\nimport { TENANT_ID } from './constants';\nimport { EndpointRouter } from './endpointRouter';\nimport { createRequestContext } from './fnValidators';\nimport { RequestContextBuilder, ValidationPipeline } from './handlerUtils';\nimport { createApiErrorResponse } from './responses';\nimport type { TernSecureHandlerOptions, TernSecureInternalHandlerConfig } from './types';\nimport { DEFAULT_HANDLER_OPTIONS } from './types';\nimport { ConfigUtils } from './utils';\n\nclass HandlerConfigFactory {\n static create(options?: TernSecureHandlerOptions): TernSecureInternalHandlerConfig {\n const baseConfig: Required<TernSecureHandlerOptions> = ConfigUtils.mergeWithDefaults(\n DEFAULT_HANDLER_OPTIONS,\n options,\n );\n\n return {\n ...baseConfig,\n tenantId: TENANT_ID,\n };\n }\n}\n\nclass TernSecureRequestHandler {\n private readonly config: TernSecureInternalHandlerConfig;\n\n constructor(config: TernSecureInternalHandlerConfig) {\n this.config = config;\n }\n\n async handle(request: Request): Promise<Response> {\n const handlerContext = RequestContextBuilder.create(request);\n const validationContext = createRequestContext(request);\n\n try {\n const validationResult = await this.executeValidation(validationContext);\n if (validationResult) {\n return validationResult;\n }\n\n return await EndpointRouter.route(handlerContext, this.config);\n } catch (error) {\n return createApiErrorResponse('INTERNAL_SERVER_ERROR', 'Internal server error', 500);\n }\n }\n\n private async executeValidation(validationContext: any): Promise<Response | null> {\n const validationPipeline = new ValidationPipeline(this.config, validationContext);\n return validationPipeline.execute();\n }\n}\n\nexport function createTernSecureNextJsHandler(options: TernSecureHandlerOptions) {\n const config = HandlerConfigFactory.create(options);\n const requestHandler = new TernSecureRequestHandler(config);\n\n const handler = async (request: Request) => await requestHandler.handle(request);\n\n //const handler = async (request: Request): Promise<Response> => {\n // const context = await createRequestProcessor(createTernSecureRequest(request), options);\n // const { validateCors, validateSecurity } = createValidators(context);\n // await validateCors(options.cors || '');\n // await validateSecurity(options.security || {});\n //};\n\n return {\n GET: handler,\n POST: handler,\n } as const;\n}\n"],"mappings":"AACA,SAAS,iBAAiB;AAC1B,SAAS,sBAAsB;AAC/B,SAAS,4BAA4B;AACrC,SAAS,uBAAuB,0BAA0B;AAC1D,SAAS,8BAA8B;AAEvC,SAAS,+BAA+B;AACxC,SAAS,mBAAmB;AAE5B,MAAM,qBAAqB;AAAA,EACzB,OAAO,OAAO,SAAqE;AACjF,UAAM,aAAiD,YAAY;AAAA,MACjE;AAAA,MACA;AAAA,IACF;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEA,MAAM,yBAAyB;AAAA,EACZ;AAAA,EAEjB,YAAY,QAAyC;AACnD,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,OAAO,SAAqC;AAChD,UAAM,iBAAiB,sBAAsB,OAAO,OAAO;AAC3D,UAAM,oBAAoB,qBAAqB,OAAO;AAEtD,QAAI;AACF,YAAM,mBAAmB,MAAM,KAAK,kBAAkB,iBAAiB;AACvE,UAAI,kBAAkB;AACpB,eAAO;AAAA,MACT;AAEA,aAAO,MAAM,eAAe,MAAM,gBAAgB,KAAK,MAAM;AAAA,IAC/D,SAAS,OAAO;AACd,aAAO,uBAAuB,yBAAyB,yBAAyB,GAAG;AAAA,IACrF;AAAA,EACF;AAAA,EAEA,MAAc,kBAAkB,mBAAkD;AAChF,UAAM,qBAAqB,IAAI,mBAAmB,KAAK,QAAQ,iBAAiB;AAChF,WAAO,mBAAmB,QAAQ;AAAA,EACpC;AACF;AAEO,SAAS,8BAA8B,SAAmC;AAC/E,QAAM,SAAS,qBAAqB,OAAO,OAAO;AAClD,QAAM,iBAAiB,IAAI,yBAAyB,MAAM;AAE1D,QAAM,UAAU,OAAO,YAAqB,MAAM,eAAe,OAAO,OAAO;AAS/E,SAAO;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AACF;","names":[]}
@@ -9,7 +9,6 @@ const DEFAULT_CORS_OPTIONS = {
9
9
  const DEFAULT_COOKIE_OPTIONS = {
10
10
  name: "__session",
11
11
  path: "/",
12
- secure: true,
13
12
  httpOnly: true,
14
13
  sameSite: "lax",
15
14
  maxAge: 3600 * 24 * 7
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/types.ts"],"sourcesContent":["import { type NextResponse } from 'next/server';\n\nexport interface CorsOptions {\n allowedOrigins: string[] | '*';\n allowedMethods?: string[];\n allowedHeaders?: string[];\n allowCredentials?: boolean;\n maxAge?: number;\n skipSameOrigin?: boolean;\n}\n\nexport interface CookieOptions {\n name?: string;\n domain?: string;\n path?: string;\n secure?: boolean;\n httpOnly?: boolean;\n sameSite?: 'strict' | 'lax' | 'none';\n maxAge?: number;\n}\n\nexport interface RateLimitOptions {\n windowMs?: number;\n maxRequests?: number;\n skipSuccessful?: boolean;\n skipFailedRequests?: boolean;\n}\n\nexport interface SecurityOptions {\n requireCSRF?: boolean;\n allowedReferers?: string[];\n requiredHeaders?: Record<string, string>;\n ipWhitelist?: string[];\n userAgent?: {\n block?: string[];\n allow?: string[];\n };\n}\n\nexport interface EndpointConfig {\n enabled: boolean;\n methods: ('GET' | 'POST' | 'PUT' | 'DELETE')[];\n requireAuth?: boolean;\n rateLimit?: RateLimitOptions;\n security?: SecurityOptions;\n cors?: Partial<CorsOptions>;\n}\n\nexport interface SessionEndpointConfig extends EndpointConfig {\n subEndpoints?: {\n [K in SessionSubEndpoint]?: Partial<EndpointConfig>;\n };\n}\n\nexport interface TernSecureHandlerOptions {\n cors?: CorsOptions;\n cookies?: CookieOptions;\n rateLimit?: RateLimitOptions;\n security?: SecurityOptions;\n endpoints?: {\n sessions?: SessionEndpointConfig;\n };\n\n debug?: boolean;\n environment?: 'development' | 'production' | 'test';\n basePath?: string;\n}\n\n/**\n * Define an internal config type that extends the public options\n * with server-side only values like tenantId.\n */\nexport type TernSecureInternalHandlerConfig = Required<TernSecureHandlerOptions> & {\n tenantId?: string;\n};\n\nexport type AuthEndpoint = 'sessions' | 'users';\nexport type SessionSubEndpoint = 'verify' | 'createsession' | 'refresh' | 'revoke';\n\nexport const DEFAULT_CORS_OPTIONS: CorsOptions = {\n allowedOrigins: [],\n allowedMethods: ['GET', 'POST'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],\n allowCredentials: true,\n maxAge: 86400, // 24 hours\n};\n\nexport const DEFAULT_COOKIE_OPTIONS: CookieOptions = {\n name: '__session',\n path: '/',\n secure: true,\n httpOnly: true,\n sameSite: 'lax',\n maxAge: 3600 * 24 * 7, // 7 days\n};\n\nexport const DEFAULT_SECURITY_OPTIONS: SecurityOptions = {\n requireCSRF: true,\n allowedReferers: [],\n requiredHeaders: {},\n ipWhitelist: [],\n userAgent: {\n block: [],\n allow: [],\n },\n};\n\nexport const DEFAULT_ENDPOINT_CONFIG: EndpointConfig = {\n enabled: true,\n methods: ['GET', 'POST'],\n requireAuth: false,\n security: DEFAULT_SECURITY_OPTIONS,\n};\n\nexport const DEFAULT_SESSIONS_CONFIG: SessionEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n verify: {\n enabled: true,\n methods: ['GET'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n allowedReferers: [],\n },\n },\n createsession: {\n enabled: true,\n methods: ['POST'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n },\n },\n refresh: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n revoke: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n },\n};\n\nexport const DEFAULT_HANDLER_OPTIONS: Required<TernSecureHandlerOptions> & {\n endpoints: Required<NonNullable<TernSecureHandlerOptions['endpoints']>>;\n} = {\n cors: DEFAULT_CORS_OPTIONS,\n cookies: DEFAULT_COOKIE_OPTIONS,\n rateLimit: {\n windowMs: 15 * 60 * 1000, // 15 minutes\n maxRequests: 100,\n skipSuccessful: false,\n skipFailedRequests: false,\n },\n security: DEFAULT_SECURITY_OPTIONS,\n endpoints: {\n sessions: DEFAULT_SESSIONS_CONFIG,\n },\n debug: false,\n environment: 'production',\n basePath: '/api/auth',\n};\n\n\nexport interface ValidationResult {\n error?: NextResponse;\n data?: any;\n}\n\nexport interface ValidationConfig {\n cors?: CorsOptions;\n security?: SecurityOptions;\n endpoint?: {\n name: AuthEndpoint;\n config: EndpointConfig;\n };\n subEndpoint?: {\n name: SessionSubEndpoint;\n config: EndpointConfig;\n };\n requireIdToken?: boolean;\n requireCsrfToken?: boolean;\n}\n\nexport interface ComprehensiveValidationResult {\n isValid: boolean;\n error?: NextResponse;\n corsResponse?: NextResponse;\n sessionData?: {\n body: any;\n idToken?: string;\n csrfToken?: string;\n };\n}\n"],"mappings":"AA+EO,MAAM,uBAAoC;AAAA,EAC/C,gBAAgB,CAAC;AAAA,EACjB,gBAAgB,CAAC,OAAO,MAAM;AAAA,EAC9B,gBAAgB,CAAC,gBAAgB,iBAAiB,kBAAkB;AAAA,EACpE,kBAAkB;AAAA,EAClB,QAAQ;AAAA;AACV;AAEO,MAAM,yBAAwC;AAAA,EACnD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ,OAAO,KAAK;AAAA;AACtB;AAEO,MAAM,2BAA4C;AAAA,EACvD,aAAa;AAAA,EACb,iBAAiB,CAAC;AAAA,EAClB,iBAAiB,CAAC;AAAA,EAClB,aAAa,CAAC;AAAA,EACd,WAAW;AAAA,IACT,OAAO,CAAC;AAAA,IACR,OAAO,CAAC;AAAA,EACV;AACF;AAEO,MAAM,0BAA0C;AAAA,EACrD,SAAS;AAAA,EACT,SAAS,CAAC,OAAO,MAAM;AAAA,EACvB,aAAa;AAAA,EACb,UAAU;AACZ;AAEO,MAAM,0BAAiD;AAAA,EAC5D,GAAG;AAAA,EACH,cAAc;AAAA,IACZ,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,SAAS,CAAC,KAAK;AAAA,MACf,aAAa;AAAA,MACb,UAAU;AAAA,QACR,aAAa;AAAA,QACb,iBAAiB,CAAC;AAAA,MACpB;AAAA,IACF;AAAA,IACA,eAAe;AAAA,MACb,SAAS;AAAA,MACT,SAAS,CAAC,MAAM;AAAA,MAChB,aAAa;AAAA,MACb,UAAU;AAAA,QACR,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,SAAS;AAAA,MACT,SAAS,CAAC,MAAM;AAAA,MAChB,aAAa;AAAA,MACb,UAAU;AAAA,QACR,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,SAAS,CAAC,MAAM;AAAA,MAChB,aAAa;AAAA,MACb,UAAU;AAAA,QACR,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,0BAET;AAAA,EACF,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,IACT,UAAU,KAAK,KAAK;AAAA;AAAA,IACpB,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,EACtB;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,IACT,UAAU;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AACZ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/types.ts"],"sourcesContent":["import { type NextResponse } from 'next/server';\n\nexport interface CorsOptions {\n allowedOrigins: string[] | '*';\n allowedMethods?: string[];\n allowedHeaders?: string[];\n allowCredentials?: boolean;\n maxAge?: number;\n skipSameOrigin?: boolean;\n}\n\nexport interface CookieOptions {\n name?: string;\n domain?: string;\n path?: string;\n httpOnly?: boolean;\n sameSite?: 'strict' | 'lax' | 'none';\n maxAge?: number;\n}\n\nexport interface RateLimitOptions {\n windowMs?: number;\n maxRequests?: number;\n skipSuccessful?: boolean;\n skipFailedRequests?: boolean;\n}\n\nexport interface SecurityOptions {\n requireCSRF?: boolean;\n allowedReferers?: string[];\n requiredHeaders?: Record<string, string>;\n ipWhitelist?: string[];\n userAgent?: {\n block?: string[];\n allow?: string[];\n };\n}\n\nexport interface EndpointConfig {\n enabled: boolean;\n methods: ('GET' | 'POST' | 'PUT' | 'DELETE')[];\n requireAuth?: boolean;\n rateLimit?: RateLimitOptions;\n security?: SecurityOptions;\n cors?: Partial<CorsOptions>;\n}\n\nexport interface SessionEndpointConfig extends EndpointConfig {\n subEndpoints?: {\n [K in SessionSubEndpoint]?: Partial<EndpointConfig>;\n };\n}\n\nexport interface TernSecureHandlerOptions {\n cors?: CorsOptions;\n cookies?: CookieOptions;\n rateLimit?: RateLimitOptions;\n security?: SecurityOptions;\n endpoints?: {\n sessions?: SessionEndpointConfig;\n };\n\n debug?: boolean;\n environment?: 'development' | 'production' | 'test';\n basePath?: string;\n}\n\n/**\n * Define an internal config type that extends the public options\n * with server-side only values like tenantId.\n */\nexport type TernSecureInternalHandlerConfig = Required<TernSecureHandlerOptions> & {\n tenantId?: string;\n};\n\nexport type AuthEndpoint = 'sessions' | 'users';\nexport type SessionSubEndpoint = 'verify' | 'createsession' | 'refresh' | 'revoke';\n\nexport const DEFAULT_CORS_OPTIONS: CorsOptions = {\n allowedOrigins: [],\n allowedMethods: ['GET', 'POST'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],\n allowCredentials: true,\n maxAge: 86400, // 24 hours\n};\n\nexport const DEFAULT_COOKIE_OPTIONS: CookieOptions = {\n name: '__session',\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n maxAge: 3600 * 24 * 7, // 7 days\n};\n\nexport const DEFAULT_SECURITY_OPTIONS: SecurityOptions = {\n requireCSRF: true,\n allowedReferers: [],\n requiredHeaders: {},\n ipWhitelist: [],\n userAgent: {\n block: [],\n allow: [],\n },\n};\n\nexport const DEFAULT_ENDPOINT_CONFIG: EndpointConfig = {\n enabled: true,\n methods: ['GET', 'POST'],\n requireAuth: false,\n security: DEFAULT_SECURITY_OPTIONS,\n};\n\nexport const DEFAULT_SESSIONS_CONFIG: SessionEndpointConfig = {\n ...DEFAULT_ENDPOINT_CONFIG,\n subEndpoints: {\n verify: {\n enabled: true,\n methods: ['GET'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n allowedReferers: [],\n },\n },\n createsession: {\n enabled: true,\n methods: ['POST'],\n requireAuth: false,\n security: {\n requireCSRF: true,\n },\n },\n refresh: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n revoke: {\n enabled: true,\n methods: ['POST'],\n requireAuth: true,\n security: {\n requireCSRF: true,\n },\n },\n },\n};\n\nexport const DEFAULT_HANDLER_OPTIONS: Required<TernSecureHandlerOptions> & {\n endpoints: Required<NonNullable<TernSecureHandlerOptions['endpoints']>>;\n} = {\n cors: DEFAULT_CORS_OPTIONS,\n cookies: DEFAULT_COOKIE_OPTIONS,\n rateLimit: {\n windowMs: 15 * 60 * 1000, // 15 minutes\n maxRequests: 100,\n skipSuccessful: false,\n skipFailedRequests: false,\n },\n security: DEFAULT_SECURITY_OPTIONS,\n endpoints: {\n sessions: DEFAULT_SESSIONS_CONFIG,\n },\n debug: false,\n environment: 'production',\n basePath: '/api/auth',\n};\n\n\nexport interface ValidationResult {\n error?: NextResponse;\n data?: any;\n}\n\nexport interface ValidationConfig {\n cors?: CorsOptions;\n security?: SecurityOptions;\n endpoint?: {\n name: AuthEndpoint;\n config: EndpointConfig;\n };\n subEndpoint?: {\n name: SessionSubEndpoint;\n config: EndpointConfig;\n };\n requireIdToken?: boolean;\n requireCsrfToken?: boolean;\n}\n\nexport interface ComprehensiveValidationResult {\n isValid: boolean;\n error?: Response;\n corsResponse?: Response;\n sessionData?: {\n body: any;\n idToken?: string;\n csrfToken?: string;\n };\n}\n"],"mappings":"AA8EO,MAAM,uBAAoC;AAAA,EAC/C,gBAAgB,CAAC;AAAA,EACjB,gBAAgB,CAAC,OAAO,MAAM;AAAA,EAC9B,gBAAgB,CAAC,gBAAgB,iBAAiB,kBAAkB;AAAA,EACpE,kBAAkB;AAAA,EAClB,QAAQ;AAAA;AACV;AAEO,MAAM,yBAAwC;AAAA,EACnD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ,OAAO,KAAK;AAAA;AACtB;AAEO,MAAM,2BAA4C;AAAA,EACvD,aAAa;AAAA,EACb,iBAAiB,CAAC;AAAA,EAClB,iBAAiB,CAAC;AAAA,EAClB,aAAa,CAAC;AAAA,EACd,WAAW;AAAA,IACT,OAAO,CAAC;AAAA,IACR,OAAO,CAAC;AAAA,EACV;AACF;AAEO,MAAM,0BAA0C;AAAA,EACrD,SAAS;AAAA,EACT,SAAS,CAAC,OAAO,MAAM;AAAA,EACvB,aAAa;AAAA,EACb,UAAU;AACZ;AAEO,MAAM,0BAAiD;AAAA,EAC5D,GAAG;AAAA,EACH,cAAc;AAAA,IACZ,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,SAAS,CAAC,KAAK;AAAA,MACf,aAAa;AAAA,MACb,UAAU;AAAA,QACR,aAAa;AAAA,QACb,iBAAiB,CAAC;AAAA,MACpB;AAAA,IACF;AAAA,IACA,eAAe;AAAA,MACb,SAAS;AAAA,MACT,SAAS,CAAC,MAAM;AAAA,MAChB,aAAa;AAAA,MACb,UAAU;AAAA,QACR,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,SAAS;AAAA,MACT,SAAS,CAAC,MAAM;AAAA,MAChB,aAAa;AAAA,MACb,UAAU;AAAA,QACR,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,SAAS,CAAC,MAAM;AAAA,MAChB,aAAa;AAAA,MACb,UAAU;AAAA,QACR,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAEO,MAAM,0BAET;AAAA,EACF,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,IACT,UAAU,KAAK,KAAK;AAAA;AAAA,IACpB,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,EACtB;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,IACT,UAAU;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,EACP,aAAa;AAAA,EACb,UAAU;AACZ;","names":[]}
@@ -1,4 +1,3 @@
1
- import { NextResponse } from "next/server";
2
1
  import { createApiErrorResponse } from "./responses";
3
2
  class CorsValidator {
4
3
  static async validate(request, corsOptions) {
@@ -22,7 +21,7 @@ class CorsValidator {
22
21
  return null;
23
22
  }
24
23
  static createOptionsResponse(corsOptions) {
25
- const response = new NextResponse(null, { status: 204 });
24
+ const response = new Response(null, { status: 204 });
26
25
  if (corsOptions.allowedOrigins === "*") {
27
26
  response.headers.set("Access-Control-Allow-Origin", "*");
28
27
  } else {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/app-router/admin/validators.ts"],"sourcesContent":["import type { NextRequest} from 'next/server';\nimport { NextResponse } from 'next/server';\n\nimport { createApiErrorResponse } from './responses';\nimport type { AuthEndpoint, CorsOptions, SecurityOptions, SessionSubEndpoint } from './types';\n\n/**\n * CORS validation utilities\n */\nexport class CorsValidator {\n static async validate(\n request: NextRequest,\n corsOptions: CorsOptions,\n ): Promise<NextResponse | null> {\n const origin = request.headers.get('origin');\n const host = request.headers.get('host');\n\n // Skip CORS for same-origin requests\n if (!origin || (host && origin.includes(host))) {\n return null;\n }\n\n if (corsOptions.allowedOrigins !== '*') {\n const isAllowed = corsOptions.allowedOrigins.some(allowedOrigin => {\n if (allowedOrigin.startsWith('*')) {\n const domain = allowedOrigin.slice(1);\n return origin?.endsWith(domain);\n }\n return origin === allowedOrigin;\n });\n\n if (!isAllowed) {\n return createApiErrorResponse('CORS_ORIGIN_NOT_ALLOWED', 'Origin not allowed', 403);\n }\n }\n\n return null;\n }\n\n static createOptionsResponse(corsOptions: CorsOptions): NextResponse {\n const response = new NextResponse(null, { status: 204 });\n\n if (corsOptions.allowedOrigins === '*') {\n response.headers.set('Access-Control-Allow-Origin', '*');\n } else {\n response.headers.set('Access-Control-Allow-Origin', corsOptions.allowedOrigins.join(','));\n }\n\n response.headers.set(\n 'Access-Control-Allow-Methods',\n corsOptions.allowedMethods?.join(',') || 'GET,POST',\n );\n response.headers.set(\n 'Access-Control-Allow-Headers',\n corsOptions.allowedHeaders?.join(',') || 'Content-Type,Authorization',\n );\n\n if (corsOptions.allowCredentials) {\n response.headers.set('Access-Control-Allow-Credentials', 'true');\n }\n\n if (corsOptions.maxAge) {\n response.headers.set('Access-Control-Max-Age', corsOptions.maxAge.toString());\n }\n\n return response;\n }\n}\n\n/**\n * Security validation utilities\n */\nexport class SecurityValidator {\n static async validate(\n request: NextRequest,\n securityOptions: SecurityOptions,\n ): Promise<NextResponse | null> {\n const origin = request.headers.get('origin');\n const host = request.headers.get('host');\n const referer = request.headers.get('referer');\n const userAgent = request.headers.get('user-agent') || '';\n\n // CSRF Protection for cross-origin requests\n const csrfResult = this.validateCsrf(request, securityOptions, origin, host, referer);\n if (csrfResult) return csrfResult;\n\n // Required headers validation\n const headersResult = this.validateRequiredHeaders(request, securityOptions);\n if (headersResult) return headersResult;\n\n // User Agent filtering\n const userAgentResult = this.validateUserAgent(userAgent, securityOptions);\n if (userAgentResult) return userAgentResult;\n\n return null;\n }\n\n private static validateCsrf(\n request: NextRequest,\n securityOptions: SecurityOptions,\n origin: string | null,\n host: string | null,\n referer: string | null,\n ): NextResponse | null {\n if (securityOptions.requireCSRF && origin && host && !origin.includes(host)) {\n const hasCSRFHeader = request.headers.get('x-requested-with') === 'XMLHttpRequest';\n const hasValidReferer = referer && host && referer.includes(host);\n\n if (!hasCSRFHeader && !hasValidReferer) {\n const isAllowedReferer = securityOptions.allowedReferers?.some((allowedRef: string) =>\n referer?.includes(allowedRef),\n );\n\n if (!isAllowedReferer) {\n return createApiErrorResponse('CSRF_PROTECTION', 'Access denied', 403);\n }\n }\n }\n return null;\n }\n\n private static validateRequiredHeaders(\n request: NextRequest,\n securityOptions: SecurityOptions,\n ): NextResponse | null {\n if (securityOptions.requiredHeaders) {\n for (const [headerName, expectedValue] of Object.entries(securityOptions.requiredHeaders)) {\n const actualValue = request.headers.get(headerName);\n if (actualValue !== expectedValue) {\n return createApiErrorResponse(\n 'INVALID_HEADERS',\n 'Required header missing or invalid',\n 400,\n );\n }\n }\n }\n return null;\n }\n\n private static validateUserAgent(\n userAgent: string,\n securityOptions: SecurityOptions,\n ): NextResponse | null {\n // User Agent blocking\n if (securityOptions.userAgent?.block?.length) {\n const isBlocked = securityOptions.userAgent.block.some((blocked: string) =>\n userAgent.toLowerCase().includes(blocked.toLowerCase()),\n );\n\n if (isBlocked) {\n return createApiErrorResponse('USER_AGENT_BLOCKED', 'Access denied', 403);\n }\n }\n\n // User Agent allowlist\n if (securityOptions.userAgent?.allow?.length) {\n const isAllowed = securityOptions.userAgent.allow.some((allowed: string) =>\n userAgent.toLowerCase().includes(allowed.toLowerCase()),\n );\n\n if (!isAllowed) {\n return createApiErrorResponse('USER_AGENT_NOT_ALLOWED', 'Access denied', 403);\n }\n }\n\n return null;\n }\n}\n\n/**\n * CSRF token validation utilities\n */\nexport class CsrfValidator {\n static validate(csrfToken: string, csrfCookieValue: string | undefined): NextResponse | null {\n if (!csrfToken) {\n return createApiErrorResponse('INVALID_CSRF_TOKEN', 'CSRF token is required', 400);\n }\n\n if (!csrfCookieValue) {\n return createApiErrorResponse('CSRF_COOKIE_MISSING', 'CSRF token cookie not found', 403);\n }\n\n if (csrfToken !== csrfCookieValue) {\n return createApiErrorResponse('CSRF_TOKEN_MISMATCH', 'CSRF token mismatch', 403);\n }\n\n return null;\n }\n}\n\n/**\n * Route validation utilities\n */\nexport class RouteValidator {\n static validatePathStructure(pathSegments: string[]): NextResponse | null {\n if (pathSegments.length < 3) {\n return createApiErrorResponse(\n 'INVALID_ROUTE',\n 'Invalid route structure. Expected: /api/auth/{endpoint}',\n 404,\n );\n }\n return null;\n }\n\n static validateEndpoint(\n _endpoint: AuthEndpoint,\n endpointConfig: any,\n method: string,\n ): NextResponse | null {\n if (!endpointConfig || !endpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (method !== 'OPTIONS' && !endpointConfig.methods.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n\n static validateSubEndpoint(\n subEndpoint: SessionSubEndpoint | undefined,\n subEndpointConfig: any,\n method: string,\n ): NextResponse | null {\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (!subEndpointConfig.methods?.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n}\n\n/**\n * Request body validation utilities\n */\nexport class RequestValidator {\n static async validateSessionRequest(request: NextRequest): Promise<{\n body: any;\n idToken?: string;\n csrfToken?: string;\n error?: NextResponse;\n }> {\n try {\n const body = await request.json();\n return { body, idToken: body.idToken, csrfToken: body.csrfToken };\n } catch (error) {\n return {\n body: null,\n error: createApiErrorResponse('INVALID_REQUEST_FORMAT', 'Invalid request format', 400),\n };\n }\n }\n\n static validateIdToken(idToken: string | undefined): NextResponse | null {\n if (!idToken) {\n return createApiErrorResponse(\n 'INVALID_TOKEN',\n 'ID token is required for creating session',\n 400,\n );\n }\n return null;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/app-router/admin/validators.ts"],"sourcesContent":["import { createApiErrorResponse } from './responses';\nimport type { AuthEndpoint, CorsOptions, SecurityOptions, SessionSubEndpoint } from './types';\n\n/**\n * CORS validation utilities\n */\nexport class CorsValidator {\n static async validate(\n request: Request,\n corsOptions: CorsOptions,\n ): Promise<Response | null> {\n const origin = request.headers.get('origin');\n const host = request.headers.get('host');\n\n // Skip CORS for same-origin requests\n if (!origin || (host && origin.includes(host))) {\n return null;\n }\n\n if (corsOptions.allowedOrigins !== '*') {\n const isAllowed = corsOptions.allowedOrigins.some(allowedOrigin => {\n if (allowedOrigin.startsWith('*')) {\n const domain = allowedOrigin.slice(1);\n return origin?.endsWith(domain);\n }\n return origin === allowedOrigin;\n });\n\n if (!isAllowed) {\n return createApiErrorResponse('CORS_ORIGIN_NOT_ALLOWED', 'Origin not allowed', 403);\n }\n }\n\n return null;\n }\n\n static createOptionsResponse(corsOptions: CorsOptions): Response {\n const response = new Response(null, { status: 204 });\n\n if (corsOptions.allowedOrigins === '*') {\n response.headers.set('Access-Control-Allow-Origin', '*');\n } else {\n response.headers.set('Access-Control-Allow-Origin', corsOptions.allowedOrigins.join(','));\n }\n\n response.headers.set(\n 'Access-Control-Allow-Methods',\n corsOptions.allowedMethods?.join(',') || 'GET,POST',\n );\n response.headers.set(\n 'Access-Control-Allow-Headers',\n corsOptions.allowedHeaders?.join(',') || 'Content-Type,Authorization',\n );\n\n if (corsOptions.allowCredentials) {\n response.headers.set('Access-Control-Allow-Credentials', 'true');\n }\n\n if (corsOptions.maxAge) {\n response.headers.set('Access-Control-Max-Age', corsOptions.maxAge.toString());\n }\n\n return response;\n }\n}\n\n/**\n * Security validation utilities\n */\nexport class SecurityValidator {\n static async validate(\n request: Request,\n securityOptions: SecurityOptions,\n ): Promise<Response | null> {\n const origin = request.headers.get('origin');\n const host = request.headers.get('host');\n const referer = request.headers.get('referer');\n const userAgent = request.headers.get('user-agent') || '';\n\n // CSRF Protection for cross-origin requests\n const csrfResult = this.validateCsrf(request, securityOptions, origin, host, referer);\n if (csrfResult) return csrfResult;\n\n // Required headers validation\n const headersResult = this.validateRequiredHeaders(request, securityOptions);\n if (headersResult) return headersResult;\n\n // User Agent filtering\n const userAgentResult = this.validateUserAgent(userAgent, securityOptions);\n if (userAgentResult) return userAgentResult;\n\n return null;\n }\n\n private static validateCsrf(\n request: Request,\n securityOptions: SecurityOptions,\n origin: string | null,\n host: string | null,\n referer: string | null,\n ): Response | null {\n if (securityOptions.requireCSRF && origin && host && !origin.includes(host)) {\n const hasCSRFHeader = request.headers.get('x-requested-with') === 'XMLHttpRequest';\n const hasValidReferer = referer && host && referer.includes(host);\n\n if (!hasCSRFHeader && !hasValidReferer) {\n const isAllowedReferer = securityOptions.allowedReferers?.some((allowedRef: string) =>\n referer?.includes(allowedRef),\n );\n\n if (!isAllowedReferer) {\n return createApiErrorResponse('CSRF_PROTECTION', 'Access denied', 403);\n }\n }\n }\n return null;\n }\n\n private static validateRequiredHeaders(\n request: Request,\n securityOptions: SecurityOptions,\n ): Response | null {\n if (securityOptions.requiredHeaders) {\n for (const [headerName, expectedValue] of Object.entries(securityOptions.requiredHeaders)) {\n const actualValue = request.headers.get(headerName);\n if (actualValue !== expectedValue) {\n return createApiErrorResponse(\n 'INVALID_HEADERS',\n 'Required header missing or invalid',\n 400,\n );\n }\n }\n }\n return null;\n }\n\n private static validateUserAgent(\n userAgent: string,\n securityOptions: SecurityOptions,\n ): Response | null {\n // User Agent blocking\n if (securityOptions.userAgent?.block?.length) {\n const isBlocked = securityOptions.userAgent.block.some((blocked: string) =>\n userAgent.toLowerCase().includes(blocked.toLowerCase()),\n );\n\n if (isBlocked) {\n return createApiErrorResponse('USER_AGENT_BLOCKED', 'Access denied', 403);\n }\n }\n\n // User Agent allowlist\n if (securityOptions.userAgent?.allow?.length) {\n const isAllowed = securityOptions.userAgent.allow.some((allowed: string) =>\n userAgent.toLowerCase().includes(allowed.toLowerCase()),\n );\n\n if (!isAllowed) {\n return createApiErrorResponse('USER_AGENT_NOT_ALLOWED', 'Access denied', 403);\n }\n }\n\n return null;\n }\n}\n\n/**\n * CSRF token validation utilities\n */\nexport class CsrfValidator {\n static validate(csrfToken: string, csrfCookieValue: string | undefined): Response | null {\n if (!csrfToken) {\n return createApiErrorResponse('INVALID_CSRF_TOKEN', 'CSRF token is required', 400);\n }\n\n if (!csrfCookieValue) {\n return createApiErrorResponse('CSRF_COOKIE_MISSING', 'CSRF token cookie not found', 403);\n }\n\n if (csrfToken !== csrfCookieValue) {\n return createApiErrorResponse('CSRF_TOKEN_MISMATCH', 'CSRF token mismatch', 403);\n }\n\n return null;\n }\n}\n\n/**\n * Route validation utilities\n */\nexport class RouteValidator {\n static validatePathStructure(pathSegments: string[]): Response | null {\n if (pathSegments.length < 3) {\n return createApiErrorResponse(\n 'INVALID_ROUTE',\n 'Invalid route structure. Expected: /api/auth/{endpoint}',\n 404,\n );\n }\n return null;\n }\n\n static validateEndpoint(\n _endpoint: AuthEndpoint,\n endpointConfig: any,\n method: string,\n ): Response | null {\n if (!endpointConfig || !endpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (method !== 'OPTIONS' && !endpointConfig.methods.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n\n static validateSubEndpoint(\n subEndpoint: SessionSubEndpoint | undefined,\n subEndpointConfig: any,\n method: string,\n ): Response | null {\n if (!subEndpoint) {\n return createApiErrorResponse('SUB_ENDPOINT_REQUIRED', 'Session sub-endpoint required', 400);\n }\n\n if (!subEndpointConfig || !subEndpointConfig.enabled) {\n return createApiErrorResponse('ENDPOINT_NOT_FOUND', 'Endpoint not found', 404);\n }\n\n if (!subEndpointConfig.methods?.includes(method as any)) {\n return createApiErrorResponse('METHOD_NOT_ALLOWED', 'Method not allowed', 405);\n }\n\n return null;\n }\n}\n\n/**\n * Request body validation utilities\n */\nexport class RequestValidator {\n static async validateSessionRequest(request: Request): Promise<{\n body: any;\n idToken?: string;\n csrfToken?: string;\n error?: Response;\n }> {\n try {\n const body = await request.json();\n return { body, idToken: body.idToken, csrfToken: body.csrfToken };\n } catch (error) {\n return {\n body: null,\n error: createApiErrorResponse('INVALID_REQUEST_FORMAT', 'Invalid request format', 400),\n };\n }\n }\n\n static validateIdToken(idToken: string | undefined): Response | null {\n if (!idToken) {\n return createApiErrorResponse(\n 'INVALID_TOKEN',\n 'ID token is required for creating session',\n 400,\n );\n }\n return null;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/NextCookieAdapter.ts"],"sourcesContent":["import type { CookieOptions,CookieStore } from '@tern-secure/types';\nimport { cookies } from 'next/headers';\n\nexport class NextCookieStore implements CookieStore {\n async get(name: string): Promise<{ value: string | undefined }> {\n const cookieStore = await cookies();\n const cookie = cookieStore.get(name);\n return { value: cookie?.value };\n }\n\n async set(name: string, value: string, options: CookieOptions): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(name, value, options);\n }\n\n async delete(name: string): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.delete(name);\n }\n}"],"mappings":"AACA,SAAS,eAAe;AAEjB,MAAM,gBAAuC;AAAA,EAClD,MAAM,IAAI,MAAsD;AAC9D,UAAM,cAAc,MAAM,QAAQ;AAClC,UAAM,SAAS,YAAY,IAAI,IAAI;AACnC,WAAO,EAAE,OAAO,QAAQ,MAAM;AAAA,EAChC;AAAA,EAEA,MAAM,IAAI,MAAc,OAAe,SAAuC;AAC5E,UAAM,cAAc,MAAM,QAAQ;AAClC,gBAAY,IAAI,MAAM,OAAO,OAAO;AAAA,EACtC;AAAA,EAEA,MAAM,OAAO,MAA6B;AACxC,UAAM,cAAc,MAAM,QAAQ;AAClC,gBAAY,OAAO,IAAI;AAAA,EACzB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/NextCookieAdapter.ts"],"sourcesContent":["import type { CookieOptions, CookieStore } from '@tern-secure/types';\nimport { cookies } from 'next/headers';\n\nexport class NextCookieStore implements CookieStore {\n async get(name: string): Promise<{ value: string | undefined }> {\n const cookieStore = await cookies();\n const cookie = cookieStore.get(name);\n return { value: cookie?.value };\n }\n\n async set(name: string, value: string, options: CookieOptions): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(name, value, options);\n }\n\n async delete(name: string): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.delete(name);\n }\n}"],"mappings":"AACA,SAAS,eAAe;AAEjB,MAAM,gBAAuC;AAAA,EAClD,MAAM,IAAI,MAAsD;AAC9D,UAAM,cAAc,MAAM,QAAQ;AAClC,UAAM,SAAS,YAAY,IAAI,IAAI;AACnC,WAAO,EAAE,OAAO,QAAQ,MAAM;AAAA,EAChC;AAAA,EAEA,MAAM,IAAI,MAAc,OAAe,SAAuC;AAC5E,UAAM,cAAc,MAAM,QAAQ;AAClC,gBAAY,IAAI,MAAM,OAAO,OAAO;AAAA,EACtC;AAAA,EAEA,MAAM,OAAO,MAA6B;AACxC,UAAM,cAAc,MAAM,QAAQ;AAClC,gBAAY,OAAO,IAAI;AAAA,EACzB;AACF;","names":[]}
@@ -0,0 +1,19 @@
1
+ import type { AuthEndpoint, SessionSubEndpoint, TernSecureInternalHandlerConfig } from '../../types';
2
+ export interface HandlerContext {
3
+ request: Request;
4
+ pathSegments: string[];
5
+ endpoint: AuthEndpoint;
6
+ subEndpoint: SessionSubEndpoint | undefined;
7
+ method: string;
8
+ }
9
+ export interface EndpointHandler {
10
+ canHandle(endpoint: AuthEndpoint): boolean;
11
+ handle(handlerContext: HandlerContext, config: TernSecureInternalHandlerConfig): Promise<Response>;
12
+ }
13
+ export declare abstract class BaseEndpointHandler implements EndpointHandler {
14
+ abstract canHandle(endpoint: AuthEndpoint): boolean;
15
+ abstract handle(handlerContext: HandlerContext, config: TernSecureInternalHandlerConfig): Promise<Response>;
16
+ protected validateMethod(allowedMethods: string[], method: string): boolean;
17
+ protected validateSubEndpoint(subEndpoint: SessionSubEndpoint | undefined, requiredSubEndpoint?: boolean): boolean;
18
+ }
19
+ //# sourceMappingURL=abstract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abstract.d.ts","sourceRoot":"","sources":["../../../../../../src/app-router/admin/api/endpoints/abstract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,+BAA+B,EAChC,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC;IAC3C,MAAM,CACJ,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,QAAQ,CAAC,CAAC;CACtB;AAED,8BAAsB,mBAAoB,YAAW,eAAe;IAClE,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO;IACnD,QAAQ,CAAC,MAAM,CACb,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,QAAQ,CAAC;IAEpB,SAAS,CAAC,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAI3E,SAAS,CAAC,mBAAmB,CAC3B,WAAW,EAAE,kBAAkB,GAAG,SAAS,EAC3C,mBAAmB,CAAC,EAAE,OAAO,GAC5B,OAAO;CAMX"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../../../../src/app-router/admin/api/endpoints/sessions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=users.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../../../../../src/app-router/admin/api/endpoints/users.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ import type { TernSecureRequest } from '@tern-secure/backend';
2
+ import type { TernSecureHandlerOptions } from './types';
3
+ /**
4
+ * Request context for better type safety and clarity
5
+ */
6
+ interface RequestProcessorContext extends TernSecureHandlerOptions {
7
+ sessionTokenInHeader: string | undefined;
8
+ origin: string | undefined;
9
+ host: string | undefined;
10
+ forwardedHost: string | undefined;
11
+ forwardedProto: string | undefined;
12
+ referrer: string | undefined;
13
+ userAgent: string | undefined;
14
+ secFetchDest: string | undefined;
15
+ accept: string | undefined;
16
+ sessionTokenInCookie: string | undefined;
17
+ refreshTokenInCookie: string | undefined;
18
+ csrfTokenInCookie: string | undefined;
19
+ ternUrl: URL;
20
+ }
21
+ /**
22
+ * Request processor utility class for common operations
23
+ */
24
+ declare class RequestProcessorContext implements RequestProcessorContext {
25
+ private ternSecureRequest;
26
+ private options;
27
+ constructor(ternSecureRequest: TernSecureRequest, options: TernSecureHandlerOptions);
28
+ private initHeaderValues;
29
+ private initCookieValues;
30
+ private getQueryParam;
31
+ private getHeader;
32
+ private getCookie;
33
+ private parseAuthorizationHeader;
34
+ }
35
+ export type { RequestProcessorContext };
36
+ export declare const createRequestProcessor: (ternSecureRequest: TernSecureRequest, options: TernSecureHandlerOptions) => Promise<RequestProcessorContext>;
37
+ //# sourceMappingURL=claude-authenticateRequestProcessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-authenticateRequestProcessor.d.ts","sourceRoot":"","sources":["../../../../src/app-router/admin/claude-authenticateRequestProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,OAAO,KAAK,EAAE,wBAAwB,EAAC,MAAM,SAAS,CAAC;AAEvD;;GAEG;AACH,UAAU,uBAAwB,SAAQ,wBAAwB;IAEhE,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAG3B,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC,OAAO,EAAE,GAAG,CAAC;CACd;AAED;;GAEG;AACH,cAAM,uBAAwB,YAAW,uBAAuB;IAE5D,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,OAAO;gBADP,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,EAAE,wBAAwB;IAO3C,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,wBAAwB;CAqBjC;AAED,YAAY,EAAE,uBAAuB,EAAE,CAAC;AAExC,eAAO,MAAM,sBAAsB,GACjC,mBAAmB,iBAAiB,EACpC,SAAS,wBAAwB,KAChC,OAAO,CAAC,uBAAuB,CAEjC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { EndpointHandler } from './api/endpoints/abstract';
2
+ import type { HandlerContext } from './handlerUtils';
3
+ import type { TernSecureInternalHandlerConfig } from './types';
4
+ export declare class EndpointRouter {
5
+ private static readonly handlers;
6
+ static route(handlerContext: HandlerContext, config: TernSecureInternalHandlerConfig): Promise<Response>;
7
+ static addHandler(handler: EndpointHandler): void;
8
+ static removeHandler(predicate: (handler: EndpointHandler) => boolean): void;
9
+ }
10
+ //# sourceMappingURL=endpointRouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpointRouter.d.ts","sourceRoot":"","sources":["../../../../src/app-router/admin/endpointRouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAC,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,KAAK,EAAgB,+BAA+B,EAAE,MAAM,SAAS,CAAC;AA+B7E,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAG9B;WAEW,KAAK,CAChB,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,+BAA+B,GACtC,OAAO,CAAC,QAAQ,CAAC;IAYpB,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAIjD,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,GAAG,IAAI;CAM7E"}
@@ -1,7 +1,6 @@
1
- import { type NextRequest, NextResponse } from 'next/server';
2
1
  import type { AuthEndpoint, ComprehensiveValidationResult, CorsOptions, EndpointConfig, SecurityOptions, SessionSubEndpoint, ValidationConfig } from './types';
3
2
  export interface RequestContext {
4
- request: NextRequest;
3
+ request: Request;
5
4
  origin: string | null;
6
5
  host: string | null;
7
6
  referer: string | null;
@@ -9,7 +8,7 @@ export interface RequestContext {
9
8
  method: string;
10
9
  pathSegments: string[];
11
10
  }
12
- export declare function createRequestContext(request: NextRequest): RequestContext;
11
+ export declare function createRequestContext(request: Request): RequestContext;
13
12
  /**
14
13
  * Main validators factory function
15
14
  * Returns an object containing all validator functions and utilities
@@ -17,19 +16,19 @@ export declare function createRequestContext(request: NextRequest): RequestConte
17
16
  export declare function createValidators(context: RequestContext): {
18
17
  createValidationConfig: (overrides?: Partial<ValidationConfig>) => ValidationConfig;
19
18
  validateRequest: (config: ValidationConfig) => Promise<ComprehensiveValidationResult>;
20
- validateCors: (corsOptions: CorsOptions) => Promise<NextResponse | null>;
21
- validateSecurity: (securityOptions: SecurityOptions) => Promise<NextResponse | null>;
22
- validatePathStructure: () => NextResponse | null;
23
- validateEndpoint: (_endpoint: AuthEndpoint, endpointConfig: EndpointConfig) => NextResponse | null;
24
- validateSubEndpoint: (subEndpoint: SessionSubEndpoint | undefined, subEndpointConfig: any) => NextResponse | null;
19
+ validateCors: (corsOptions: CorsOptions) => Promise<Response | null>;
20
+ validateSecurity: (securityOptions: SecurityOptions) => Promise<Response | null>;
21
+ validatePathStructure: () => Response | null;
22
+ validateEndpoint: (_endpoint: AuthEndpoint, endpointConfig: EndpointConfig) => Response | null;
23
+ validateSubEndpoint: (subEndpoint: SessionSubEndpoint | undefined, subEndpointConfig: any) => Response | null;
25
24
  validateSessionRequest: () => Promise<{
26
25
  body: any;
27
26
  idToken?: string;
28
27
  csrfToken?: string;
29
- error?: NextResponse;
28
+ error?: Response;
30
29
  }>;
31
- validateIdToken: (idToken: string | undefined) => NextResponse | null;
32
- validateCsrfToken: (csrfToken: string, csrfCookieValue: string | undefined) => NextResponse | null;
33
- createCorsOptionsResponse: (corsOptions: CorsOptions) => NextResponse;
30
+ validateIdToken: (idToken: string | undefined) => Response | null;
31
+ validateCsrfToken: (csrfToken: string, csrfCookieValue: string | undefined) => Response | null;
32
+ createCorsOptionsResponse: (corsOptions: CorsOptions) => Response;
34
33
  };
35
34
  //# sourceMappingURL=fnValidators.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fnValidators.d.ts","sourceRoot":"","sources":["../../../../src/app-router/admin/fnValidators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG7D,OAAO,KAAK,EACV,YAAY,EACZ,6BAA6B,EAC7B,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAazE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc;yCA4SX,OAAO,CAAC,gBAAgB,CAAC,KAAQ,gBAAgB;8BA7ErD,gBAAgB,KAAG,OAAO,CAAC,6BAA6B,CAAC;gCA5NvD,WAAW,KAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;wCAqDlC,eAAe,KAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;iCA0F7D,YAAY,GAAG,IAAI;kCAYxC,YAAY,kBACP,cAAc,KAC7B,YAAY,GAAG,IAAI;uCAaP,kBAAkB,GAAG,SAAS,qBACxB,GAAG,KACrB,YAAY,GAAG,IAAI;kCAgBmB,OAAO,CAAC;QAC/C,IAAI,EAAE,GAAG,CAAC;QACV,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,YAAY,CAAC;KACtB,CAAC;+BAYgC,MAAM,GAAG,SAAS,KAAG,YAAY,GAAG,IAAI;mCAhF7D,MAAM,mBACA,MAAM,GAAG,SAAS,KAClC,YAAY,GAAG,IAAI;6CAvG0B,WAAW,KAAG,YAAY;EAuS3E"}
1
+ {"version":3,"file":"fnValidators.d.ts","sourceRoot":"","sources":["../../../../src/app-router/admin/fnValidators.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,YAAY,EACZ,6BAA6B,EAC7B,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAGjB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAarE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc;yCA6SX,OAAO,CAAC,gBAAgB,CAAC,KAAQ,gBAAgB;8BA9ErD,gBAAgB,KAAG,OAAO,CAAC,6BAA6B,CAAC;gCA5NvD,WAAW,KAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;wCAqD9B,eAAe,KAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;iCA0FzD,QAAQ,GAAG,IAAI;kCAYpC,YAAY,kBACP,cAAc,KAC7B,QAAQ,GAAG,IAAI;uCAaH,kBAAkB,GAAG,SAAS,qBACxB,GAAG,KACrB,QAAQ,GAAG,IAAI;kCAgBuB,OAAO,CAAC;QAC/C,IAAI,EAAE,GAAG,CAAC;QACV,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,QAAQ,CAAC;KAClB,CAAC;+BAYgC,MAAM,GAAG,SAAS,KAAG,QAAQ,GAAG,IAAI;mCAhFzD,MAAM,mBACA,MAAM,GAAG,SAAS,KAClC,QAAQ,GAAG,IAAI;6CAvG8B,WAAW,KAAG,QAAQ;EAwSvE"}
@@ -0,0 +1,19 @@
1
+ import type { RequestContext } from './fnValidators';
2
+ import type { AuthEndpoint, SessionSubEndpoint, TernSecureHandlerOptions } from './types';
3
+ export interface HandlerContext {
4
+ request: Request;
5
+ pathSegments: string[];
6
+ endpoint: AuthEndpoint;
7
+ subEndpoint: SessionSubEndpoint | undefined;
8
+ method: string;
9
+ }
10
+ export declare class RequestContextBuilder {
11
+ static create(request: Request): HandlerContext;
12
+ }
13
+ export declare class ValidationPipeline {
14
+ private readonly config;
15
+ private readonly context;
16
+ constructor(config: Required<TernSecureHandlerOptions>, context: RequestContext);
17
+ execute(): Promise<Response | null>;
18
+ }
19
+ //# sourceMappingURL=handlerUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlerUtils.d.ts","sourceRoot":"","sources":["../../../../src/app-router/admin/handlerUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,qBAAqB;IAChC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc;CAYhD;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;gBAGvC,MAAM,EAAE,QAAQ,CAAC,wBAAwB,CAAC,EAC1C,OAAO,EAAE,cAAc;IAMnB,OAAO,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CAe1C"}
@@ -1,4 +1,7 @@
1
1
  export { createTernSecureNextJsHandler } from './ternsecureNextjsHandler';
2
2
  export { clearSessionCookieServer, clearNextSessionCookie, createSessionCookieServer, createNextSessionCookie, setNextServerSession, setNextServerToken } from './actions';
3
- export type { TernSecureHandlerOptions } from './types';
3
+ export { EndpointRouter } from './endpointRouter';
4
+ export { RequestContextBuilder, ValidationPipeline } from './handlerUtils';
5
+ export type { HandlerContext } from './handlerUtils';
6
+ export type { TernSecureHandlerOptions, TernSecureInternalHandlerConfig } from './types';
4
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/app-router/admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAA;AAEzE,OAAO,EACH,wBAAwB,EACxB,sBAAsB,EACtB,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EACrB,MAAM,WAAW,CAAA;AAElB,YAAY,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/app-router/admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAA;AAEzE,OAAO,EACH,wBAAwB,EACxB,sBAAsB,EACtB,yBAAyB,EACzB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EACrB,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAC1E,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,YAAY,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,SAAS,CAAA"}