next-api-layer 0.1.5

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.
@@ -0,0 +1,300 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { R as ResolvedRateLimitConfig, a as ResolvedCsrfConfig, A as AuthProxyConfig, I as InternalProxyConfig, b as AuditEventType, c as ResolvedAuditConfig, T as TokenInfo, d as RefreshResult, C as CookieOptions, E as EndpointConfig } from './createApiClient-CIDYcpNI.cjs';
3
+ export { e as AccessConfig, f as ApiClient, g as ApiClientConfig, h as ApiResponse, i as AuditConfig, j as AuditEvent, k as AuthData, l as AuthResult, m as CookieConfig, n as CsrfConfig, G as GuestTokenConfig, o as I18nConfig, p as RateLimitConfig, q as ResponseMappers, S as SanitizationConfig, U as UserData, r as createApiClient } from './createApiClient-CIDYcpNI.cjs';
4
+
5
+ /**
6
+ * Rate Limiting
7
+ *
8
+ * Implements token bucket algorithm for rate limiting.
9
+ * In-memory store by default, designed for single-instance deployments.
10
+ *
11
+ * For horizontal scaling (multiple instances), use a custom store
12
+ * with Redis or similar distributed cache.
13
+ */
14
+
15
+ interface RateLimitResult {
16
+ allowed: boolean;
17
+ remaining: number;
18
+ resetAt: number;
19
+ limit: number;
20
+ }
21
+ /**
22
+ * Creates a rate limiter with in-memory store
23
+ */
24
+ declare function createRateLimiter(config: ResolvedRateLimitConfig): {
25
+ check: (req: NextRequest) => RateLimitResult;
26
+ applyHeaders: (response: NextResponse, result: RateLimitResult) => NextResponse;
27
+ createLimitedResponse: (req: NextRequest, result: RateLimitResult) => NextResponse;
28
+ shouldSkip: (pathname: string) => boolean;
29
+ reset: (key: string) => void;
30
+ clear: () => void;
31
+ size: () => number;
32
+ };
33
+ type RateLimiter = ReturnType<typeof createRateLimiter>;
34
+
35
+ /**
36
+ * CSRF Protection
37
+ *
38
+ * Implements OWASP recommended CSRF protection:
39
+ * - Fetch Metadata (Sec-Fetch-Site header) for modern browsers (98%+ coverage)
40
+ * - Signed HMAC Double-Submit Cookie as fallback
41
+ *
42
+ * @see https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
43
+ */
44
+
45
+ interface CsrfValidationResult {
46
+ valid: boolean;
47
+ reason?: string;
48
+ }
49
+ /**
50
+ * Creates CSRF validator functions
51
+ */
52
+ declare function createCsrfValidator(config: ResolvedCsrfConfig): {
53
+ validateRequest: (req: NextRequest) => CsrfValidationResult;
54
+ generateToken: (sessionId: string) => Promise<string>;
55
+ attachCsrfCookie: (response: NextResponse, sessionId: string) => Promise<NextResponse>;
56
+ };
57
+ type CsrfValidator = ReturnType<typeof createCsrfValidator>;
58
+
59
+ /**
60
+ * Creates an authentication proxy middleware for Next.js
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * // middleware.ts
65
+ * import { createAuthProxy } from 'next-api-layer';
66
+ *
67
+ * const authProxy = createAuthProxy({
68
+ * apiBaseUrl: process.env.API_BASE_URL!,
69
+ * cookies: {
70
+ * user: 'userAuthToken',
71
+ * guest: 'guestAuthToken',
72
+ * },
73
+ * guestToken: {
74
+ * enabled: true,
75
+ * credentials: {
76
+ * username: process.env.GUEST_USERNAME!,
77
+ * password: process.env.GUEST_PASSWORD!,
78
+ * },
79
+ * },
80
+ * access: {
81
+ * protectedRoutes: ['/dashboard', '/profile'],
82
+ * authRoutes: ['/login', '/register'],
83
+ * },
84
+ * // Security features
85
+ * csrf: { enabled: true },
86
+ * rateLimit: { enabled: true, maxRequests: 100 },
87
+ * audit: {
88
+ * enabled: true,
89
+ * logger: (event) => console.log('[AUDIT]', event)
90
+ * },
91
+ * });
92
+ *
93
+ * export default authProxy;
94
+ *
95
+ * export const config = {
96
+ * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
97
+ * };
98
+ * ```
99
+ */
100
+ declare function createAuthProxy(userConfig: AuthProxyConfig): {
101
+ (req: NextRequest): Promise<NextResponse>;
102
+ config: InternalProxyConfig;
103
+ csrf: {
104
+ validateRequest: (req: NextRequest) => CsrfValidationResult;
105
+ generateToken: (sessionId: string) => Promise<string>;
106
+ attachCsrfCookie: (response: NextResponse, sessionId: string) => Promise<NextResponse>;
107
+ };
108
+ rateLimiter: {
109
+ check: (req: NextRequest) => RateLimitResult;
110
+ applyHeaders: (response: NextResponse, result: RateLimitResult) => NextResponse;
111
+ createLimitedResponse: (req: NextRequest, result: RateLimitResult) => NextResponse;
112
+ shouldSkip: (pathname: string) => boolean;
113
+ reset: (key: string) => void;
114
+ clear: () => void;
115
+ size: () => number;
116
+ };
117
+ audit: {
118
+ emit: (type: AuditEventType, req: NextRequest, options: {
119
+ success: boolean;
120
+ userId?: string;
121
+ metadata?: Record<string, unknown>;
122
+ }) => Promise<void>;
123
+ isEnabled: (type: AuditEventType) => boolean;
124
+ authSuccess: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
125
+ authFail: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
126
+ authRefresh: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
127
+ authGuest: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
128
+ accessDenied: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
129
+ csrfFail: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
130
+ rateLimitExceeded: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
131
+ error: (req: NextRequest, err: Error, metadata?: Record<string, unknown>) => Promise<void>;
132
+ };
133
+ };
134
+ type AuthProxy = ReturnType<typeof createAuthProxy>;
135
+
136
+ /**
137
+ * createProxyHandler
138
+ * Factory function to create Next.js API route handlers that proxy requests to backend
139
+ */
140
+
141
+ interface ProxyHandlerConfig {
142
+ /** Base URL of the backend API */
143
+ apiBaseUrl: string;
144
+ /** Cookie name for user auth token */
145
+ userCookieName?: string;
146
+ /** Cookie name for guest auth token */
147
+ guestCookieName?: string;
148
+ /**
149
+ * Default behavior for auth - if true, all requests skip auth by default
150
+ * Individual requests can override with X-Skip-Auth header
151
+ */
152
+ skipAuthByDefault?: boolean;
153
+ /**
154
+ * Public endpoints that should never include auth token (glob patterns)
155
+ * e.g., ['news/*', 'public/**', 'categories']
156
+ */
157
+ publicEndpoints?: string[];
158
+ /** Headers to forward from client request */
159
+ forwardHeaders?: string[];
160
+ /** Headers to exclude from forwarding */
161
+ excludeHeaders?: string[];
162
+ /** Custom request transformer */
163
+ transformRequest?: (req: NextRequest, headers: Headers) => Headers | Promise<Headers>;
164
+ /** Custom response transformer */
165
+ transformResponse?: (response: Response) => Response | Promise<Response>;
166
+ }
167
+ /**
168
+ * Creates a proxy handler for Next.js API routes
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * // app/api/[...path]/route.ts
173
+ * import { createProxyHandler } from 'next-api-layer';
174
+ *
175
+ * const handler = createProxyHandler({
176
+ * apiBaseUrl: process.env.API_BASE_URL!,
177
+ * userCookieName: 'auth_token',
178
+ * guestCookieName: 'guest_token',
179
+ * publicEndpoints: ['news/*', 'categories', 'public/**'],
180
+ * });
181
+ *
182
+ * export const GET = handler;
183
+ * export const POST = handler;
184
+ * export const PUT = handler;
185
+ * export const PATCH = handler;
186
+ * export const DELETE = handler;
187
+ * ```
188
+ */
189
+ declare function createProxyHandler(config: ProxyHandlerConfig): {
190
+ (req: NextRequest): Promise<NextResponse>;
191
+ config: ProxyHandlerConfig;
192
+ };
193
+ type ProxyHandler = ReturnType<typeof createProxyHandler>;
194
+
195
+ /**
196
+ * Audit Logging
197
+ *
198
+ * Event-based security audit logging system.
199
+ * Emits events for authentication, access control, and security violations.
200
+ */
201
+
202
+ /**
203
+ * Creates an audit logger instance
204
+ */
205
+ declare function createAuditLogger(config: ResolvedAuditConfig): {
206
+ emit: (type: AuditEventType, req: NextRequest, options: {
207
+ success: boolean;
208
+ userId?: string;
209
+ metadata?: Record<string, unknown>;
210
+ }) => Promise<void>;
211
+ isEnabled: (type: AuditEventType) => boolean;
212
+ authSuccess: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
213
+ authFail: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
214
+ authRefresh: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
215
+ authGuest: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
216
+ accessDenied: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
217
+ csrfFail: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
218
+ rateLimitExceeded: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
219
+ error: (req: NextRequest, err: Error, metadata?: Record<string, unknown>) => Promise<void>;
220
+ };
221
+ type AuditLogger = ReturnType<typeof createAuditLogger>;
222
+
223
+ /**
224
+ * Token Validation
225
+ * Handles token validation and refresh with backend API
226
+ */
227
+
228
+ /**
229
+ * Creates token validation functions
230
+ */
231
+ declare function createTokenValidation(config: InternalProxyConfig): {
232
+ validateToken: (token: string) => Promise<TokenInfo>;
233
+ getTokenInfo: (token: string) => Promise<TokenInfo>;
234
+ refreshToken: (oldToken: string) => Promise<RefreshResult>;
235
+ createGuestToken: () => Promise<string | null>;
236
+ };
237
+ type TokenValidation = ReturnType<typeof createTokenValidation>;
238
+
239
+ /**
240
+ * Proxy Handlers
241
+ * Request handling logic for different scenarios
242
+ */
243
+
244
+ /**
245
+ * Creates proxy handlers
246
+ */
247
+ declare function createHandlers(config: InternalProxyConfig, validation: TokenValidation): {
248
+ deleteAllAuthCookies: (req: NextRequest, response: NextResponse) => NextResponse;
249
+ jsonError: (message: string, status?: number) => NextResponse;
250
+ isAuthPage: (pathname: string) => boolean;
251
+ isProtectedRoute: (pathname: string) => boolean;
252
+ isPublicRoute: (pathname: string) => boolean;
253
+ isTokenTypeAllowed: (tokenType: string | null) => boolean;
254
+ handleNoToken: (req: NextRequest, isApiRoute: boolean) => Promise<NextResponse>;
255
+ handleValidationResult: (req: NextRequest, tokenInfo: TokenInfo, isUserToken: boolean, currentToken: string, isApiRoute: boolean) => Promise<NextResponse>;
256
+ };
257
+
258
+ /**
259
+ * Shared Constants
260
+ * Default values and constant configurations
261
+ */
262
+
263
+ declare const DEFAULT_COOKIE_OPTIONS: Required<CookieOptions>;
264
+ declare const DEFAULT_ENDPOINTS: Required<EndpointConfig>;
265
+ declare const TOKEN_TYPES: {
266
+ readonly GUEST: "guest";
267
+ };
268
+ declare const ERROR_MESSAGES: {
269
+ readonly NO_TOKEN: "Token bulunamadı.";
270
+ readonly INVALID_TOKEN: "Token geçersiz veya süresi dolmuş.";
271
+ readonly CONNECTION_ERROR: "Bağlantı hatası oluştu.";
272
+ readonly UNAUTHORIZED: "Bu işlem için yetkiniz yok.";
273
+ };
274
+ declare const HEADERS: {
275
+ readonly AUTH_USER: "x-auth-user";
276
+ readonly REFRESHED_TOKEN: "x-refreshed-token";
277
+ readonly AUTHORIZATION: "Authorization";
278
+ readonly CONTENT_TYPE: "Content-Type";
279
+ readonly SKIP_AUTH: "x-skip-auth";
280
+ readonly LOCALE: "x-locale";
281
+ };
282
+ /** CSRF safe methods that don't need validation */
283
+ declare const CSRF_SAFE_METHODS: readonly ["GET", "HEAD", "OPTIONS"];
284
+ declare const DEFAULT_CSRF_CONFIG: {
285
+ readonly strategy: "both";
286
+ readonly cookieName: "__csrf";
287
+ readonly headerName: "x-csrf-token";
288
+ readonly ignoreMethods: readonly ["GET", "HEAD", "OPTIONS"];
289
+ readonly trustSameSite: false;
290
+ };
291
+ declare const DEFAULT_RATE_LIMIT_CONFIG: {
292
+ readonly windowMs: number;
293
+ readonly maxRequests: 100;
294
+ readonly skipRoutes: string[];
295
+ };
296
+ declare const DEFAULT_AUDIT_CONFIG: {
297
+ readonly events: readonly ["auth:success", "auth:fail", "auth:refresh", "access:denied", "csrf:fail", "rateLimit:exceeded", "error"];
298
+ };
299
+
300
+ export { AuditEventType, type AuditLogger, type AuthProxy, AuthProxyConfig, CSRF_SAFE_METHODS, CookieOptions, type CsrfValidator, DEFAULT_AUDIT_CONFIG, DEFAULT_COOKIE_OPTIONS, DEFAULT_CSRF_CONFIG, DEFAULT_ENDPOINTS, DEFAULT_RATE_LIMIT_CONFIG, ERROR_MESSAGES, EndpointConfig, HEADERS, type ProxyHandler, type ProxyHandlerConfig, type RateLimiter, TOKEN_TYPES, TokenInfo, createAuditLogger, createAuthProxy, createCsrfValidator, createHandlers, createProxyHandler, createRateLimiter, createTokenValidation };
@@ -0,0 +1,300 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { R as ResolvedRateLimitConfig, a as ResolvedCsrfConfig, A as AuthProxyConfig, I as InternalProxyConfig, b as AuditEventType, c as ResolvedAuditConfig, T as TokenInfo, d as RefreshResult, C as CookieOptions, E as EndpointConfig } from './createApiClient-CIDYcpNI.js';
3
+ export { e as AccessConfig, f as ApiClient, g as ApiClientConfig, h as ApiResponse, i as AuditConfig, j as AuditEvent, k as AuthData, l as AuthResult, m as CookieConfig, n as CsrfConfig, G as GuestTokenConfig, o as I18nConfig, p as RateLimitConfig, q as ResponseMappers, S as SanitizationConfig, U as UserData, r as createApiClient } from './createApiClient-CIDYcpNI.js';
4
+
5
+ /**
6
+ * Rate Limiting
7
+ *
8
+ * Implements token bucket algorithm for rate limiting.
9
+ * In-memory store by default, designed for single-instance deployments.
10
+ *
11
+ * For horizontal scaling (multiple instances), use a custom store
12
+ * with Redis or similar distributed cache.
13
+ */
14
+
15
+ interface RateLimitResult {
16
+ allowed: boolean;
17
+ remaining: number;
18
+ resetAt: number;
19
+ limit: number;
20
+ }
21
+ /**
22
+ * Creates a rate limiter with in-memory store
23
+ */
24
+ declare function createRateLimiter(config: ResolvedRateLimitConfig): {
25
+ check: (req: NextRequest) => RateLimitResult;
26
+ applyHeaders: (response: NextResponse, result: RateLimitResult) => NextResponse;
27
+ createLimitedResponse: (req: NextRequest, result: RateLimitResult) => NextResponse;
28
+ shouldSkip: (pathname: string) => boolean;
29
+ reset: (key: string) => void;
30
+ clear: () => void;
31
+ size: () => number;
32
+ };
33
+ type RateLimiter = ReturnType<typeof createRateLimiter>;
34
+
35
+ /**
36
+ * CSRF Protection
37
+ *
38
+ * Implements OWASP recommended CSRF protection:
39
+ * - Fetch Metadata (Sec-Fetch-Site header) for modern browsers (98%+ coverage)
40
+ * - Signed HMAC Double-Submit Cookie as fallback
41
+ *
42
+ * @see https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
43
+ */
44
+
45
+ interface CsrfValidationResult {
46
+ valid: boolean;
47
+ reason?: string;
48
+ }
49
+ /**
50
+ * Creates CSRF validator functions
51
+ */
52
+ declare function createCsrfValidator(config: ResolvedCsrfConfig): {
53
+ validateRequest: (req: NextRequest) => CsrfValidationResult;
54
+ generateToken: (sessionId: string) => Promise<string>;
55
+ attachCsrfCookie: (response: NextResponse, sessionId: string) => Promise<NextResponse>;
56
+ };
57
+ type CsrfValidator = ReturnType<typeof createCsrfValidator>;
58
+
59
+ /**
60
+ * Creates an authentication proxy middleware for Next.js
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * // middleware.ts
65
+ * import { createAuthProxy } from 'next-api-layer';
66
+ *
67
+ * const authProxy = createAuthProxy({
68
+ * apiBaseUrl: process.env.API_BASE_URL!,
69
+ * cookies: {
70
+ * user: 'userAuthToken',
71
+ * guest: 'guestAuthToken',
72
+ * },
73
+ * guestToken: {
74
+ * enabled: true,
75
+ * credentials: {
76
+ * username: process.env.GUEST_USERNAME!,
77
+ * password: process.env.GUEST_PASSWORD!,
78
+ * },
79
+ * },
80
+ * access: {
81
+ * protectedRoutes: ['/dashboard', '/profile'],
82
+ * authRoutes: ['/login', '/register'],
83
+ * },
84
+ * // Security features
85
+ * csrf: { enabled: true },
86
+ * rateLimit: { enabled: true, maxRequests: 100 },
87
+ * audit: {
88
+ * enabled: true,
89
+ * logger: (event) => console.log('[AUDIT]', event)
90
+ * },
91
+ * });
92
+ *
93
+ * export default authProxy;
94
+ *
95
+ * export const config = {
96
+ * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
97
+ * };
98
+ * ```
99
+ */
100
+ declare function createAuthProxy(userConfig: AuthProxyConfig): {
101
+ (req: NextRequest): Promise<NextResponse>;
102
+ config: InternalProxyConfig;
103
+ csrf: {
104
+ validateRequest: (req: NextRequest) => CsrfValidationResult;
105
+ generateToken: (sessionId: string) => Promise<string>;
106
+ attachCsrfCookie: (response: NextResponse, sessionId: string) => Promise<NextResponse>;
107
+ };
108
+ rateLimiter: {
109
+ check: (req: NextRequest) => RateLimitResult;
110
+ applyHeaders: (response: NextResponse, result: RateLimitResult) => NextResponse;
111
+ createLimitedResponse: (req: NextRequest, result: RateLimitResult) => NextResponse;
112
+ shouldSkip: (pathname: string) => boolean;
113
+ reset: (key: string) => void;
114
+ clear: () => void;
115
+ size: () => number;
116
+ };
117
+ audit: {
118
+ emit: (type: AuditEventType, req: NextRequest, options: {
119
+ success: boolean;
120
+ userId?: string;
121
+ metadata?: Record<string, unknown>;
122
+ }) => Promise<void>;
123
+ isEnabled: (type: AuditEventType) => boolean;
124
+ authSuccess: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
125
+ authFail: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
126
+ authRefresh: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
127
+ authGuest: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
128
+ accessDenied: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
129
+ csrfFail: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
130
+ rateLimitExceeded: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
131
+ error: (req: NextRequest, err: Error, metadata?: Record<string, unknown>) => Promise<void>;
132
+ };
133
+ };
134
+ type AuthProxy = ReturnType<typeof createAuthProxy>;
135
+
136
+ /**
137
+ * createProxyHandler
138
+ * Factory function to create Next.js API route handlers that proxy requests to backend
139
+ */
140
+
141
+ interface ProxyHandlerConfig {
142
+ /** Base URL of the backend API */
143
+ apiBaseUrl: string;
144
+ /** Cookie name for user auth token */
145
+ userCookieName?: string;
146
+ /** Cookie name for guest auth token */
147
+ guestCookieName?: string;
148
+ /**
149
+ * Default behavior for auth - if true, all requests skip auth by default
150
+ * Individual requests can override with X-Skip-Auth header
151
+ */
152
+ skipAuthByDefault?: boolean;
153
+ /**
154
+ * Public endpoints that should never include auth token (glob patterns)
155
+ * e.g., ['news/*', 'public/**', 'categories']
156
+ */
157
+ publicEndpoints?: string[];
158
+ /** Headers to forward from client request */
159
+ forwardHeaders?: string[];
160
+ /** Headers to exclude from forwarding */
161
+ excludeHeaders?: string[];
162
+ /** Custom request transformer */
163
+ transformRequest?: (req: NextRequest, headers: Headers) => Headers | Promise<Headers>;
164
+ /** Custom response transformer */
165
+ transformResponse?: (response: Response) => Response | Promise<Response>;
166
+ }
167
+ /**
168
+ * Creates a proxy handler for Next.js API routes
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * // app/api/[...path]/route.ts
173
+ * import { createProxyHandler } from 'next-api-layer';
174
+ *
175
+ * const handler = createProxyHandler({
176
+ * apiBaseUrl: process.env.API_BASE_URL!,
177
+ * userCookieName: 'auth_token',
178
+ * guestCookieName: 'guest_token',
179
+ * publicEndpoints: ['news/*', 'categories', 'public/**'],
180
+ * });
181
+ *
182
+ * export const GET = handler;
183
+ * export const POST = handler;
184
+ * export const PUT = handler;
185
+ * export const PATCH = handler;
186
+ * export const DELETE = handler;
187
+ * ```
188
+ */
189
+ declare function createProxyHandler(config: ProxyHandlerConfig): {
190
+ (req: NextRequest): Promise<NextResponse>;
191
+ config: ProxyHandlerConfig;
192
+ };
193
+ type ProxyHandler = ReturnType<typeof createProxyHandler>;
194
+
195
+ /**
196
+ * Audit Logging
197
+ *
198
+ * Event-based security audit logging system.
199
+ * Emits events for authentication, access control, and security violations.
200
+ */
201
+
202
+ /**
203
+ * Creates an audit logger instance
204
+ */
205
+ declare function createAuditLogger(config: ResolvedAuditConfig): {
206
+ emit: (type: AuditEventType, req: NextRequest, options: {
207
+ success: boolean;
208
+ userId?: string;
209
+ metadata?: Record<string, unknown>;
210
+ }) => Promise<void>;
211
+ isEnabled: (type: AuditEventType) => boolean;
212
+ authSuccess: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
213
+ authFail: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
214
+ authRefresh: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
215
+ authGuest: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
216
+ accessDenied: (req: NextRequest, userId?: string, metadata?: Record<string, unknown>) => Promise<void>;
217
+ csrfFail: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
218
+ rateLimitExceeded: (req: NextRequest, metadata?: Record<string, unknown>) => Promise<void>;
219
+ error: (req: NextRequest, err: Error, metadata?: Record<string, unknown>) => Promise<void>;
220
+ };
221
+ type AuditLogger = ReturnType<typeof createAuditLogger>;
222
+
223
+ /**
224
+ * Token Validation
225
+ * Handles token validation and refresh with backend API
226
+ */
227
+
228
+ /**
229
+ * Creates token validation functions
230
+ */
231
+ declare function createTokenValidation(config: InternalProxyConfig): {
232
+ validateToken: (token: string) => Promise<TokenInfo>;
233
+ getTokenInfo: (token: string) => Promise<TokenInfo>;
234
+ refreshToken: (oldToken: string) => Promise<RefreshResult>;
235
+ createGuestToken: () => Promise<string | null>;
236
+ };
237
+ type TokenValidation = ReturnType<typeof createTokenValidation>;
238
+
239
+ /**
240
+ * Proxy Handlers
241
+ * Request handling logic for different scenarios
242
+ */
243
+
244
+ /**
245
+ * Creates proxy handlers
246
+ */
247
+ declare function createHandlers(config: InternalProxyConfig, validation: TokenValidation): {
248
+ deleteAllAuthCookies: (req: NextRequest, response: NextResponse) => NextResponse;
249
+ jsonError: (message: string, status?: number) => NextResponse;
250
+ isAuthPage: (pathname: string) => boolean;
251
+ isProtectedRoute: (pathname: string) => boolean;
252
+ isPublicRoute: (pathname: string) => boolean;
253
+ isTokenTypeAllowed: (tokenType: string | null) => boolean;
254
+ handleNoToken: (req: NextRequest, isApiRoute: boolean) => Promise<NextResponse>;
255
+ handleValidationResult: (req: NextRequest, tokenInfo: TokenInfo, isUserToken: boolean, currentToken: string, isApiRoute: boolean) => Promise<NextResponse>;
256
+ };
257
+
258
+ /**
259
+ * Shared Constants
260
+ * Default values and constant configurations
261
+ */
262
+
263
+ declare const DEFAULT_COOKIE_OPTIONS: Required<CookieOptions>;
264
+ declare const DEFAULT_ENDPOINTS: Required<EndpointConfig>;
265
+ declare const TOKEN_TYPES: {
266
+ readonly GUEST: "guest";
267
+ };
268
+ declare const ERROR_MESSAGES: {
269
+ readonly NO_TOKEN: "Token bulunamadı.";
270
+ readonly INVALID_TOKEN: "Token geçersiz veya süresi dolmuş.";
271
+ readonly CONNECTION_ERROR: "Bağlantı hatası oluştu.";
272
+ readonly UNAUTHORIZED: "Bu işlem için yetkiniz yok.";
273
+ };
274
+ declare const HEADERS: {
275
+ readonly AUTH_USER: "x-auth-user";
276
+ readonly REFRESHED_TOKEN: "x-refreshed-token";
277
+ readonly AUTHORIZATION: "Authorization";
278
+ readonly CONTENT_TYPE: "Content-Type";
279
+ readonly SKIP_AUTH: "x-skip-auth";
280
+ readonly LOCALE: "x-locale";
281
+ };
282
+ /** CSRF safe methods that don't need validation */
283
+ declare const CSRF_SAFE_METHODS: readonly ["GET", "HEAD", "OPTIONS"];
284
+ declare const DEFAULT_CSRF_CONFIG: {
285
+ readonly strategy: "both";
286
+ readonly cookieName: "__csrf";
287
+ readonly headerName: "x-csrf-token";
288
+ readonly ignoreMethods: readonly ["GET", "HEAD", "OPTIONS"];
289
+ readonly trustSameSite: false;
290
+ };
291
+ declare const DEFAULT_RATE_LIMIT_CONFIG: {
292
+ readonly windowMs: number;
293
+ readonly maxRequests: 100;
294
+ readonly skipRoutes: string[];
295
+ };
296
+ declare const DEFAULT_AUDIT_CONFIG: {
297
+ readonly events: readonly ["auth:success", "auth:fail", "auth:refresh", "access:denied", "csrf:fail", "rateLimit:exceeded", "error"];
298
+ };
299
+
300
+ export { AuditEventType, type AuditLogger, type AuthProxy, AuthProxyConfig, CSRF_SAFE_METHODS, CookieOptions, type CsrfValidator, DEFAULT_AUDIT_CONFIG, DEFAULT_COOKIE_OPTIONS, DEFAULT_CSRF_CONFIG, DEFAULT_ENDPOINTS, DEFAULT_RATE_LIMIT_CONFIG, ERROR_MESSAGES, EndpointConfig, HEADERS, type ProxyHandler, type ProxyHandlerConfig, type RateLimiter, TOKEN_TYPES, TokenInfo, createAuditLogger, createAuthProxy, createCsrfValidator, createHandlers, createProxyHandler, createRateLimiter, createTokenValidation };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export{d as createApiClient}from'./chunk-NBYI46RO.js';import {c,e,a,b,g,h,i}from'./chunk-XBAO7FJN.js';export{f as CSRF_SAFE_METHODS,i as DEFAULT_AUDIT_CONFIG,a as DEFAULT_COOKIE_OPTIONS,g as DEFAULT_CSRF_CONFIG,b as DEFAULT_ENDPOINTS,h as DEFAULT_RATE_LIMIT_CONFIG,d as ERROR_MESSAGES,e as HEADERS,c as TOKEN_TYPES}from'./chunk-XBAO7FJN.js';import {NextResponse}from'next/server';function ie(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID()+crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).substring(2)}`}function ue(e){return `rl:${e.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||e.headers.get("x-real-ip")||"unknown"}`}function Q(e){if(!e.apiBaseUrl)throw new Error("next-api-layer: apiBaseUrl is required");if(!e.cookies?.user||!e.cookies?.guest)throw new Error("next-api-layer: cookies.user and cookies.guest are required");let t=e.apiBaseUrl.endsWith("/")?e.apiBaseUrl:`${e.apiBaseUrl}/`,f={...a,...e.cookies.options},l={...b,...e.endpoints},m={enabled:e.csrf?.enabled??false,strategy:e.csrf?.strategy??g.strategy,secret:e.csrf?.secret??ie(),cookieName:e.csrf?.cookieName??g.cookieName,headerName:e.csrf?.headerName??g.headerName,ignoreMethods:e.csrf?.ignoreMethods??g.ignoreMethods,trustSameSite:e.csrf?.trustSameSite??g.trustSameSite},R={enabled:e.rateLimit?.enabled??false,windowMs:e.rateLimit?.windowMs??h.windowMs,maxRequests:e.rateLimit?.maxRequests??h.maxRequests,keyFn:e.rateLimit?.keyFn??ue,skipRoutes:e.rateLimit?.skipRoutes??h.skipRoutes,onRateLimited:e.rateLimit?.onRateLimited},u={enabled:e.audit?.enabled??false,events:e.audit?.events??[...i.events],logger:e.audit?.logger};return {...e,apiBaseUrl:t,_resolved:{cookieOptions:f,endpoints:l,csrf:m,rateLimit:R,audit:u}}}var $={parseAuthMe:e=>{let t=e;return !t?.success||!t?.data?null:{isValid:true,tokenType:t.data.type||"user",exp:t.data.exp||null,userData:t.data}},parseRefreshToken:e=>{let t=e;return t?.success&&t?.data?.accessToken?t.data.accessToken:null},parseGuestToken:e=>e?.data?.accessToken||null};function j(e){let{apiBaseUrl:t,_resolved:f,responseMappers:l}=e,{endpoints:m}=f,R={parseAuthMe:l?.parseAuthMe||$.parseAuthMe,parseRefreshToken:l?.parseRefreshToken||$.parseRefreshToken,parseGuestToken:l?.parseGuestToken||$.parseGuestToken};async function u(a){let i={isValid:false,tokenType:null,exp:null,userData:null};try{let n=await fetch(`${t}${m.validate}`,{headers:{Authorization:`Bearer ${a}`,"Content-Type":"application/json"},cache:"no-store"});if(!n.ok)return i;let s=await n.json().catch(()=>null),d=R.parseAuthMe(s);return !d||!d.isValid?i:d}catch{return i}}async function c(a){return u(a)}async function p(a){try{let i=await fetch(`${t}${m.refresh}`,{method:"POST",headers:{Authorization:`Bearer ${a}`,"Content-Type":"application/json"},cache:"no-store"});if(!i.ok)return {success:!1,newToken:null};let n=await i.json().catch(()=>null),s=R.parseRefreshToken(n);return s?{success:!0,newToken:s}:{success:!1,newToken:null}}catch{return {success:false,newToken:null}}}async function o(){let a=e.guestToken;if(!a?.enabled||!a.credentials)return null;try{let i=await fetch(`${t}${m.guest}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({username:a.credentials.username,password:a.credentials.password}),cache:"no-store"});if(!i.ok)return null;let n=await i.json().catch(()=>null);return R.parseGuestToken(n)}catch{return null}}return {validateToken:u,getTokenInfo:c,refreshToken:p,createGuestToken:o}}function ee(e,t){if(!t?.enabled)return null;let f=t.locales??[],l=t.defaultLocale,R=e.split("/").filter(Boolean)[0];return R&&f.includes(R)?R:l??null}function z(e$1,t){let{cookies:f,guestToken:l,access:m,i18n:R,_resolved:u}=e$1,{cookieOptions:c$1}=u;function p(r,x,h){r.cookies.get(h)?.value&&x.cookies.delete(h);}function o(r,x){return p(r,x,f.guest),p(r,x,f.user),x}function a(r,x=500){return new NextResponse(JSON.stringify({success:false,message:r}),{status:x,headers:{"Content-Type":"application/json"}})}function i(r){return (m?.authRoutes??[]).some(h=>r===h||r.startsWith(`${h}/`))}function n(r){return m?.protectedByDefault?!s(r)&&!i(r):(m?.protectedRoutes??[]).some(h=>r===h||r.startsWith(`${h}/`))}function s(r){return (m?.publicRoutes??[]).some(h=>r===h||r.startsWith(`${h}/`))}function d(r){let x=m?.allowedTokenTypes;return !x||x.length===0?true:r?x.includes(r):false}async function C(r,x){let{origin:h}=r.nextUrl;if(l?.enabled){let y=await t.createGuestToken();if(y){let N;return x?N=NextResponse.next():n(r.nextUrl.pathname)?N=NextResponse.redirect(new URL("/login",h)):N=NextResponse.next(),N.cookies.set(f.guest,y,{...c$1,maxAge:3600}),N}}return x?a("Token bulunamad\u0131",401):n(r.nextUrl.pathname)?NextResponse.redirect(new URL("/login",h)):NextResponse.next()}async function v(r,x,h,y,N){let{pathname:k,origin:g}=r.nextUrl,{isValid:S,tokenType:T,userData:A}=x,E=T===c.GUEST;if(!S){if(h&&y){let D=await t.refreshToken(y);if(D.success&&D.newToken){let O=await t.getTokenInfo(D.newToken);if(O.isValid){let _=new Headers(r.headers);O.userData&&_.set(e.AUTH_USER,JSON.stringify(O.userData)),_.set(e.REFRESHED_TOKEN,D.newToken);let Z=ee(k,R);Z&&_.set(e.LOCALE,Z);let I;return i(k)?I=NextResponse.redirect(new URL("/",g)):I=NextResponse.next({request:{headers:_}}),I.cookies.set(f.user,D.newToken,{...c$1,maxAge:c$1.maxAge}),p(r,I,f.guest),I}}}let P=await C(r,N);return P.cookies.get(f.guest)?.value?p(r,P,f.user):o(r,P),P}let U=new Headers(r.headers);A&&U.set(e.AUTH_USER,JSON.stringify(A));let J=ee(k,R);if(J&&U.set(e.LOCALE,J),!E&&!d(T)){if(N){let Y=a("Bu i\u015Flem i\xE7in yetkiniz yok",403);return o(r,Y)}let P=NextResponse.redirect(new URL("/login",g));return o(r,P)}if(E)return N?NextResponse.next({request:{headers:U}}):n(k)?NextResponse.redirect(new URL("/login",g)):NextResponse.next({request:{headers:U}});if(i(k))return NextResponse.redirect(new URL("/",g));let X=NextResponse.next({request:{headers:U}});return p(r,X,f.guest),X}return {deleteAllAuthCookies:o,jsonError:a,isAuthPage:i,isProtectedRoute:n,isPublicRoute:s,isTokenTypeAllowed:d,handleNoToken:C,handleValidationResult:v}}function K(e){async function t(u){let c=le();return `${await ce(e.secret,u,c)}.${c}`}function f(u){let c=u.method.toUpperCase();if(e.ignoreMethods.includes(c))return {valid:true};let p=e.strategy;if(p==="fetch-metadata"||p==="both"){let o=l(u);if(p==="fetch-metadata"||o.valid||o.reason!=="missing-headers")return o}return p==="double-submit"||p==="both"?m(u):{valid:true}}function l(u){let c=u.headers.get("sec-fetch-site");if(!c)return {valid:false,reason:"missing-headers"};if(c==="same-origin")return {valid:true};if(c==="none"){let p=u.method.toUpperCase();return e.ignoreMethods.includes(p)?{valid:true}:{valid:false,reason:"direct-navigation-unsafe-method"}}return c==="same-site"?e.trustSameSite?{valid:true}:{valid:false,reason:"same-site-not-trusted"}:c==="cross-site"?{valid:false,reason:"cross-site-request"}:{valid:false,reason:"unknown-sec-fetch-site"}}function m(u){let c=u.cookies.get(e.cookieName)?.value;if(!c)return {valid:false,reason:"missing-cookie-token"};let p=u.headers.get(e.headerName);return p?de(c,p)?c.split(".").length!==2?{valid:false,reason:"invalid-token-format"}:{valid:true}:{valid:false,reason:"token-mismatch"}:{valid:false,reason:"missing-header-token"}}async function R(u,c){let p=await t(c);return u.cookies.set(e.cookieName,p,{httpOnly:false,secure:process.env.NODE_ENV==="production",sameSite:"strict",path:"/"}),u}return {validateRequest:f,generateToken:t,attachCsrfCookie:R}}function le(){if(typeof crypto<"u"&&crypto.getRandomValues){let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}return Math.random().toString(36).substring(2)+Date.now().toString(36)}async function ce(e,t,f){let l=`${t.length}!${t}!${f.length}!${f}`;if(typeof crypto<"u"&&crypto.subtle){let u=new TextEncoder,c=u.encode(e),p=u.encode(l),o=await crypto.subtle.importKey("raw",c,{name:"HMAC",hash:"SHA-256"},false,["sign"]),a=await crypto.subtle.sign("HMAC",o,p);return Array.from(new Uint8Array(a),i=>i.toString(16).padStart(2,"0")).join("")}let m=0,R=e+l;for(let u=0;u<R.length;u++){let c=R.charCodeAt(u);m=(m<<5)-m+c,m=m&m;}return Math.abs(m).toString(16)}function de(e,t){if(e.length!==t.length)return false;let f=0;for(let l=0;l<e.length;l++)f|=e.charCodeAt(l)^t.charCodeAt(l);return f===0}function W(e){let t=new Map,f=setInterval(()=>{let a=Date.now();for(let[i,n]of t)n.resetAt<=a&&t.delete(i);},e.windowMs);typeof process<"u"&&process.on&&process.on("beforeExit",()=>clearInterval(f));function l(a){return e.skipRoutes.some(i=>i.endsWith("*")?a.startsWith(i.slice(0,-1)):i.endsWith("**")?a.startsWith(i.slice(0,-2)):a===i)}function m(a){let i=a.nextUrl.pathname;if(l(i))return {allowed:true,remaining:e.maxRequests,resetAt:0,limit:e.maxRequests};let n=e.keyFn(a),s=Date.now(),d=t.get(n);if(!d||d.resetAt<=s)return d={count:1,resetAt:s+e.windowMs},t.set(n,d),{allowed:true,remaining:e.maxRequests-1,resetAt:d.resetAt,limit:e.maxRequests};d.count++;let C=Math.max(0,e.maxRequests-d.count);return {allowed:d.count<=e.maxRequests,remaining:C,resetAt:d.resetAt,limit:e.maxRequests}}function R(a,i){return a.headers.set("X-RateLimit-Limit",i.limit.toString()),a.headers.set("X-RateLimit-Remaining",i.remaining.toString()),a.headers.set("X-RateLimit-Reset",Math.ceil(i.resetAt/1e3).toString()),a}function u(a,i){if(e.onRateLimited){let s=e.onRateLimited(a);return R(s,i)}let n=NextResponse.json({success:false,message:"Too many requests. Please try again later.",retryAfter:Math.ceil((i.resetAt-Date.now())/1e3)},{status:429});return n.headers.set("Retry-After",Math.ceil((i.resetAt-Date.now())/1e3).toString()),R(n,i)}function c(a){t.delete(a);}function p(){t.clear();}function o(){return t.size}return {check:m,applyHeaders:R,createLimitedResponse:u,shouldSkip:l,reset:c,clear:p,size:o}}function q(e){function t(n){return e.enabled&&e.events.includes(n)}function f(n){return n.headers.get("x-forwarded-for")?.split(",")[0]?.trim()||n.headers.get("x-real-ip")||null}async function l(n,s,d){if(!t(n))return;let C={type:n,timestamp:new Date,ip:f(s),userId:d.userId,path:s.nextUrl.pathname,method:s.method,success:d.success,metadata:d.metadata};if(e.logger)try{await e.logger(C);}catch(v){console.error("[next-api-layer] Audit logger error:",v);}}function m(n,s,d){return l("auth:success",n,{success:true,userId:s,metadata:d})}function R(n,s){return l("auth:fail",n,{success:false,metadata:s})}function u(n,s,d){return l("auth:refresh",n,{success:true,userId:s,metadata:d})}function c(n,s){return l("auth:guest",n,{success:true,metadata:s})}function p(n,s,d){return l("access:denied",n,{success:false,userId:s,metadata:d})}function o(n,s){return l("csrf:fail",n,{success:false,metadata:s})}function a(n,s){return l("rateLimit:exceeded",n,{success:false,metadata:s})}function i(n,s,d){return l("error",n,{success:false,metadata:{...d,error:s.message,stack:s.stack}})}return {emit:l,isEnabled:t,authSuccess:m,authFail:R,authRefresh:u,authGuest:c,accessDenied:p,csrfFail:o,rateLimitExceeded:a,error:i}}function te(e){let t=Q(e),f=j(t),l=z(t,f),m=K(t._resolved.csrf),R=W(t._resolved.rateLimit),u=q(t._resolved.audit);async function c(o){let{pathname:a,origin:i}=o.nextUrl,n=a.startsWith("/api");if(t._resolved.rateLimit.enabled){let g=R.check(o);if(!g.allowed)return await u.rateLimitExceeded(o,{limit:g.limit,resetAt:g.resetAt}),R.createLimitedResponse(o,g)}if(t._resolved.csrf.enabled){let g=m.validateRequest(o);if(!g.valid)return await u.csrfFail(o,{reason:g.reason}),NextResponse.json({success:false,message:"CSRF validation failed"},{status:403})}if(t.blockBrowserApiAccess&&n&&(o.headers.get("accept")||"").includes("text/html"))return NextResponse.redirect(new URL("/",i));if(t.beforeAuth){let g=await t.beforeAuth(o);if(g)return g}if((t.excludedPaths??[]).some(g=>a.startsWith(g)))return p(o,NextResponse.next(),{isAuthenticated:false,isGuest:false,tokenType:null,user:null});if(["/api/auth/login","/api/auth/logout","/api/auth/me","/api/auth/refresh","/api/auth/register"].includes(a))return p(o,NextResponse.next(),{isAuthenticated:false,isGuest:false,tokenType:null,user:null});let C=o.cookies?.get(t.cookies.user)?.value,v=o.cookies?.get(t.cookies.guest)?.value,r=C||v,x=!!C;if(!r){await u.authFail(o,{reason:"no-token"});let g=await l.handleNoToken(o,n);return p(o,g,{isAuthenticated:false,isGuest:false,tokenType:null,user:null})}let h=await f.getTokenInfo(r),y={isAuthenticated:h.isValid&&h.tokenType!=="guest",isGuest:h.isValid&&h.tokenType==="guest",tokenType:h.tokenType,user:h.userData};if(h.isValid)if(h.tokenType==="guest")await u.authGuest(o);else {let g=h.userData?.id?.toString();await u.authSuccess(o,g,{tokenType:h.tokenType});}else await u.authFail(o,{reason:"invalid-token"});let N=await l.handleValidationResult(o,h,x,r,n),k=await p(o,N,y);if(t._resolved.csrf.enabled&&y.isAuthenticated){let g=h.userData?.id?.toString()||r.slice(0,32);k=await m.attachCsrfCookie(k,g);}if(t._resolved.rateLimit.enabled){let g=R.check(o);k=R.applyHeaders(k,g);}return k}async function p(o,a,i){return t.afterAuth?t.afterAuth(o,a,i):a}return c.config=t,c.csrf=m,c.rateLimiter=R,c.audit=u,c}function pe(e,t){if(!t||t.length===0)return false;let f=e.replace(/^\/api\//,"").replace(/^\//,"");return t.some(l=>{if(l===f)return true;if(l.includes("*")){let m=l.replace(/\*\*/g,"<<<DOUBLE>>>").replace(/\*/g,"[^/]+").replace(/<<<DOUBLE>>>/g,".+");return new RegExp(`^${m}$`).test(f)}return false})}function ne(e$1){let{apiBaseUrl:t,userCookieName:f="auth_token",guestCookieName:l="guest_token",skipAuthByDefault:m=false,publicEndpoints:R=[],forwardHeaders:u=["content-type","accept","accept-language","x-requested-with"],excludeHeaders:c=["host","connection","cookie"],transformRequest:p,transformResponse:o}=e$1,a=t.replace(/\/$/,"");function i(s,d){return s.headers.get(e.SKIP_AUTH)==="true"||pe(d,R)?true:m}async function n(s){try{let d=new URL(s.url),C=d.pathname.replace(/^\/api\/?/,""),v=new URL(`${a}/${C}`);v.search=d.search;let r=new Headers;if(u.forEach(T=>{let A=s.headers.get(T);A&&r.set(T,A);}),s.headers.forEach((T,A)=>{let E=A.toLowerCase();!c.includes(E)&&!r.has(A)&&r.set(A,T);}),!i(s,C)){let T=s.cookies.get(f)?.value,A=s.cookies.get(l)?.value,E=T||A;E&&r.set(e.AUTHORIZATION,`Bearer ${E}`);}r.delete(e.SKIP_AUTH);let x=p?await p(s,r):r,h=null;if(s.method!=="GET"&&s.method!=="HEAD"){let T=s.headers.get("content-type")||"";T.includes("application/json")?h=await s.text():T.includes("multipart/form-data")?h=await s.formData():h=await s.text();}let y=await fetch(v.toString(),{method:s.method,headers:x,body:h}),N=y.headers.get("content-type")||"",k;N.includes("application/json")?k=await y.text():k=await y.arrayBuffer();let g=new Headers;y.headers.forEach((T,A)=>{let E=A.toLowerCase();["transfer-encoding","connection","keep-alive"].includes(E)||g.set(A,T);});let S=new NextResponse(k,{status:y.status,statusText:y.statusText,headers:g});return o&&(S=await o(S)),S}catch(d){return console.error("[Proxy Error]",d),NextResponse.json({success:false,message:"Proxy error: Unable to connect to backend",error:d instanceof Error?d.message:"Unknown error"},{status:502})}}return n.config=e$1,n}
2
+ export{q as createAuditLogger,te as createAuthProxy,K as createCsrfValidator,z as createHandlers,ne as createProxyHandler,W as createRateLimiter,j as createTokenValidation};//# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map