@scallywag/validation 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,403 @@
1
+ /**
2
+ * Validation Middleware
3
+ *
4
+ * Next.js API route validation middleware using Zod
5
+ */
6
+ import { NextResponse } from 'next/server';
7
+ import { SecurityLevel, } from './types';
8
+ import { formatValidationErrors, validateData } from './validators';
9
+ import { MemoryRateLimitStore } from '@scallywag/gateway/middleware/security/RateLimiter';
10
+ import { logger } from '@scallywag/security/logger';
11
+ /**
12
+ * Helper function to extract request body safely
13
+ */
14
+ async function extractRequestBody(request) {
15
+ return await request.json().catch(() => ({}));
16
+ }
17
+ /**
18
+ * Helper function to safely extract validated data from result
19
+ * Extracted for better testability
20
+ */
21
+ export function safeExtractValidatedData(result) {
22
+ return typeof result === 'object' &&
23
+ result !== null &&
24
+ 'validatedData' in result
25
+ ? result['validatedData']
26
+ : {};
27
+ }
28
+ /**
29
+ * Helper function to validate request body
30
+ */
31
+ async function validateRequestBody(config, request, errors, validatedData) {
32
+ if (!config || request.method === 'GET')
33
+ return;
34
+ const body = await extractRequestBody(request);
35
+ const bodyResult = await validateData(config, body);
36
+ if (!bodyResult.success) {
37
+ errors.push(...bodyResult.errors);
38
+ }
39
+ else {
40
+ validatedData['body'] = bodyResult.data;
41
+ }
42
+ }
43
+ /**
44
+ * Helper function to validate query parameters
45
+ */
46
+ async function validateRequestQuery(config, request, errors, validatedData) {
47
+ if (!config)
48
+ return;
49
+ const url = new URL(request.url);
50
+ const queryParams = Object.fromEntries(url.searchParams.entries());
51
+ const queryResult = await validateData(config, queryParams);
52
+ if (!queryResult.success) {
53
+ errors.push(...queryResult.errors);
54
+ }
55
+ else {
56
+ validatedData['query'] = queryResult.data;
57
+ }
58
+ }
59
+ /**
60
+ * Helper function to validate headers
61
+ */
62
+ async function validateRequestHeaders(config, request, errors, validatedData) {
63
+ if (!config)
64
+ return;
65
+ // Convert Headers to plain object (safely iterate over header entries)
66
+ const headers = {};
67
+ request.headers.forEach((value, key) => {
68
+ // Safe to use bracket notation here since we're creating a new object
69
+ // and headers from NextRequest are guaranteed to be strings
70
+ Object.defineProperty(headers, key, {
71
+ value,
72
+ enumerable: true,
73
+ writable: true,
74
+ configurable: true,
75
+ });
76
+ });
77
+ const headersResult = await validateData(config, headers);
78
+ if (!headersResult.success) {
79
+ errors.push(...headersResult.errors);
80
+ }
81
+ else {
82
+ validatedData['headers'] = headersResult.data;
83
+ }
84
+ }
85
+ /**
86
+ * Helper function to validate unified input
87
+ * Merges body, query params, and URL params into a single object
88
+ * and validates against the input schema.
89
+ */
90
+ async function validateUnifiedInput(config, request, params, errors, validatedData) {
91
+ if (!config)
92
+ return false;
93
+ // Extract URL query parameters
94
+ const url = new URL(request.url);
95
+ const queryParams = Object.fromEntries(url.searchParams.entries());
96
+ // Extract request body (if not GET)
97
+ const body = request.method !== 'GET' ? await extractRequestBody(request) : {};
98
+ // Merge all inputs: query params + URL params + body
99
+ // Later values override earlier ones (body takes precedence)
100
+ const mergedInput = Object.assign(Object.assign(Object.assign({}, queryParams), params), (typeof body === 'object' && body !== null ? body : {}));
101
+ const inputResult = await validateData(config, mergedInput);
102
+ if (!inputResult.success) {
103
+ errors.push(...inputResult.errors);
104
+ }
105
+ else {
106
+ // Store validated data at top level for easy access
107
+ validatedData['input'] = inputResult.data;
108
+ // Also store in legacy locations for backwards compatibility
109
+ validatedData['body'] = inputResult.data;
110
+ validatedData['query'] = queryParams;
111
+ }
112
+ return true; // Indicates unified validation was performed
113
+ }
114
+ /**
115
+ * Create validation middleware for API routes
116
+ *
117
+ * Supports two validation modes:
118
+ * 1. Unified input validation (config.input): Merges body, query, and params
119
+ * into a single validated object. Preferred for new endpoints.
120
+ * 2. Legacy validation (config.body/query/headers): Validates each part
121
+ * separately. Maintained for backwards compatibility.
122
+ */
123
+ export function createValidationMiddleware(config) {
124
+ return async function validationMiddleware(request, _context, params) {
125
+ const errors = [];
126
+ const validatedData = {};
127
+ const routeParams = params !== null && params !== void 0 ? params : {};
128
+ try {
129
+ // Check for unified input validation first (preferred mode)
130
+ const usedUnifiedValidation = await validateUnifiedInput(config.input, request, routeParams, errors, validatedData);
131
+ // If unified validation was used, skip legacy body/query validation
132
+ // but still validate headers if configured
133
+ if (usedUnifiedValidation) {
134
+ await validateRequestHeaders(config.headers, request, errors, validatedData);
135
+ }
136
+ else {
137
+ // Fall back to legacy validation for separate body/query/headers
138
+ await validateRequestBody(config.body, request, errors, validatedData);
139
+ await validateRequestQuery(config.query, request, errors, validatedData);
140
+ await validateRequestHeaders(config.headers, request, errors, validatedData);
141
+ }
142
+ if (errors.length > 0) {
143
+ return NextResponse.json({
144
+ success: false,
145
+ error: 'Validation failed',
146
+ details: formatValidationErrors(errors),
147
+ timestamp: new Date().toISOString(),
148
+ }, { status: 400 });
149
+ }
150
+ return { validatedData };
151
+ }
152
+ catch (error) {
153
+ logger.error('Validation middleware error', {
154
+ error: error instanceof Error ? error.message : String(error),
155
+ });
156
+ return NextResponse.json({
157
+ success: false,
158
+ error: 'Validation error',
159
+ details: { server: ['Internal validation error'] },
160
+ timestamp: new Date().toISOString(),
161
+ }, { status: 500 });
162
+ }
163
+ };
164
+ }
165
+ /**
166
+ * Validation decorator for API route handlers
167
+ *
168
+ * Supports unified input validation when config.input is provided.
169
+ * Extracts route params from the context argument automatically.
170
+ */
171
+ export function validateRoute(config) {
172
+ return function (_target, _propertyKey, descriptor) {
173
+ const originalMethod = descriptor.value;
174
+ descriptor.value = async function (request, ...args) {
175
+ const middleware = createValidationMiddleware(config);
176
+ // Extract params from context (first arg after request in Next.js)
177
+ const context = args[0];
178
+ const params = extractParamsFromContext(context);
179
+ const result = await middleware(request, undefined, params);
180
+ // Check if result is an error response
181
+ if ('status' in result && result.status !== 200) {
182
+ return result;
183
+ }
184
+ // Add validated data to the request context
185
+ const validatedData = safeExtractValidatedData(result);
186
+ return originalMethod.call(this, request, validatedData, ...args);
187
+ };
188
+ return descriptor;
189
+ };
190
+ }
191
+ /**
192
+ * Extract route params from Next.js context
193
+ */
194
+ function extractParamsFromContext(context) {
195
+ if (typeof context !== 'object' || context === null)
196
+ return undefined;
197
+ const ctx = context;
198
+ if (typeof ctx['params'] !== 'object' || ctx['params'] === null) {
199
+ return undefined;
200
+ }
201
+ // Next.js params can be strings or arrays - normalize to strings
202
+ const params = ctx['params'];
203
+ const normalized = {};
204
+ // Use Object.entries to avoid object injection sink warnings
205
+ for (const [key, value] of Object.entries(params)) {
206
+ if (typeof value === 'string') {
207
+ Object.defineProperty(normalized, key, {
208
+ value,
209
+ enumerable: true,
210
+ writable: true,
211
+ configurable: true,
212
+ });
213
+ }
214
+ else if (Array.isArray(value) && value.length > 0) {
215
+ // For catch-all routes, join array segments
216
+ Object.defineProperty(normalized, key, {
217
+ value: value.join('/'),
218
+ enumerable: true,
219
+ writable: true,
220
+ configurable: true,
221
+ });
222
+ }
223
+ }
224
+ return normalized;
225
+ }
226
+ /**
227
+ * Higher-order function to wrap API route with validation
228
+ *
229
+ * Supports unified input validation when config.input is provided.
230
+ * Extracts route params from Next.js context automatically.
231
+ */
232
+ export function withValidation(config, handler) {
233
+ return async function (request, context) {
234
+ const middleware = createValidationMiddleware(config);
235
+ const params = extractParamsFromContext(context);
236
+ const result = await middleware(request, undefined, params);
237
+ // Check if result is an error response
238
+ if ('status' in result && result.status !== 200) {
239
+ return result;
240
+ }
241
+ const validatedData = safeExtractValidatedData(result);
242
+ return handler(request, validatedData, context);
243
+ };
244
+ }
245
+ /**
246
+ * Check if user agent indicates a bot
247
+ */
248
+ function isBotUserAgent(userAgent) {
249
+ return /bot|crawler|spider/i.test(userAgent);
250
+ }
251
+ /**
252
+ * Check if user agent indicates automated tools
253
+ */
254
+ function isAutomatedToolUserAgent(userAgent) {
255
+ return /bot|crawler|spider|curl|wget/i.test(userAgent);
256
+ }
257
+ /**
258
+ * Check if user agent indicates scripting languages
259
+ */
260
+ function isScriptingUserAgent(userAgent) {
261
+ return /bot|crawler|spider|curl|wget|python|ruby|php/i.test(userAgent);
262
+ }
263
+ /**
264
+ * Perform security checks based on level
265
+ */
266
+ function performSecurityCheck(securityLevel, userAgent, origin, hasAuthorization) {
267
+ switch (securityLevel) {
268
+ case SecurityLevel.LOW:
269
+ return true;
270
+ case SecurityLevel.MEDIUM:
271
+ return !isBotUserAgent(userAgent);
272
+ case SecurityLevel.HIGH:
273
+ return !isAutomatedToolUserAgent(userAgent) && origin.length > 0;
274
+ case SecurityLevel.CRITICAL:
275
+ return (!isScriptingUserAgent(userAgent) &&
276
+ origin.length > 0 &&
277
+ hasAuthorization);
278
+ default:
279
+ return false;
280
+ }
281
+ }
282
+ /**
283
+ * Security-focused validation middleware
284
+ */
285
+ export function createSecurityMiddleware(securityLevel = SecurityLevel.MEDIUM) {
286
+ return function (request) {
287
+ var _a, _b;
288
+ const userAgent = (_a = request.headers.get('user-agent')) !== null && _a !== void 0 ? _a : '';
289
+ const origin = (_b = request.headers.get('origin')) !== null && _b !== void 0 ? _b : '';
290
+ const hasAuthorization = request.headers.has('authorization');
291
+ const passes = performSecurityCheck(securityLevel, userAgent, origin, hasAuthorization);
292
+ if (!passes) {
293
+ return NextResponse.json({
294
+ success: false,
295
+ error: 'Security check failed',
296
+ timestamp: new Date().toISOString(),
297
+ }, { status: 403 });
298
+ }
299
+ return null; // Pass security check
300
+ };
301
+ }
302
+ /**
303
+ * Rate limiting middleware
304
+ *
305
+ * Uses standardized gateway MemoryRateLimitStore for consistent rate limiting across the application.
306
+ * This maintains backward compatibility with the existing Next.js API route middleware pattern
307
+ * while using the standardized gateway rate limiting infrastructure.
308
+ */
309
+ export function createRateLimitMiddleware(requests = 100, windowMs = 60000 // 1 minute
310
+ ) {
311
+ // Use the same store implementation as the gateway for consistency
312
+ const store = new MemoryRateLimitStore();
313
+ /**
314
+ * Extract client IP from request headers
315
+ */
316
+ function extractClientIP(request) {
317
+ var _a, _b;
318
+ return (((_b = (_a = request.headers.get('x-forwarded-for')) === null || _a === void 0 ? void 0 : _a.split(',')[0]) === null || _b === void 0 ? void 0 : _b.trim()) ||
319
+ request.headers.get('x-real-ip') ||
320
+ '127.0.0.1');
321
+ }
322
+ return function (request) {
323
+ const ip = extractClientIP(request);
324
+ const key = `rate-limit:ip:${ip}`;
325
+ const now = Date.now();
326
+ // Get current rate limit info
327
+ const info = store.get(key);
328
+ // Check if rate limit exceeded
329
+ if (info && info.count >= requests) {
330
+ const retryAfter = Math.max(0, Math.ceil((info.resetTime - now) / 1000));
331
+ return NextResponse.json({
332
+ success: false,
333
+ error: 'Rate limit exceeded',
334
+ retryAfter,
335
+ timestamp: new Date().toISOString(),
336
+ }, {
337
+ status: 429,
338
+ headers: {
339
+ 'X-RateLimit-Limit': requests.toString(),
340
+ 'X-RateLimit-Remaining': '0',
341
+ 'X-RateLimit-Reset': new Date(info.resetTime).toISOString(),
342
+ 'Retry-After': retryAfter.toString(),
343
+ },
344
+ });
345
+ }
346
+ // Increment the counter (this will create entry if it doesn't exist)
347
+ store.increment(key, windowMs);
348
+ // Return null to allow the request (rate limit passed)
349
+ return null;
350
+ };
351
+ }
352
+ /**
353
+ * Combine multiple middleware functions
354
+ */
355
+ export function combineMiddleware(...middlewares) {
356
+ return function (request) {
357
+ for (const middleware of middlewares) {
358
+ const result = middleware(request);
359
+ if (result) {
360
+ return result; // Return error response from first failing middleware
361
+ }
362
+ }
363
+ return null; // All middleware passed
364
+ };
365
+ }
366
+ /**
367
+ * Create comprehensive API middleware
368
+ *
369
+ * Supports unified input validation when options.validation.input is provided.
370
+ * Accepts optional context for extracting route params.
371
+ */
372
+ export function createApiMiddleware(options) {
373
+ const middlewares = [];
374
+ // Add security middleware
375
+ if (options.security) {
376
+ middlewares.push(createSecurityMiddleware(options.security));
377
+ }
378
+ // Add rate limiting
379
+ if (options.rateLimit) {
380
+ middlewares.push(createRateLimitMiddleware(options.rateLimit.requests, options.rateLimit.windowMs));
381
+ }
382
+ const combinedMiddleware = combineMiddleware(...middlewares);
383
+ return async function (request, handler, context) {
384
+ // Run security and rate limiting checks
385
+ const middlewareResult = combinedMiddleware(request);
386
+ if (middlewareResult) {
387
+ return middlewareResult;
388
+ }
389
+ // Run validation if configured
390
+ if (options.validation) {
391
+ const validationMiddleware = createValidationMiddleware(options.validation);
392
+ const params = extractParamsFromContext(context);
393
+ const validationResult = await validationMiddleware(request, undefined, params);
394
+ if ('status' in validationResult && validationResult.status !== 200) {
395
+ return validationResult;
396
+ }
397
+ const validatedData = safeExtractValidatedData(validationResult);
398
+ return handler(request, validatedData);
399
+ }
400
+ return handler(request);
401
+ };
402
+ }
403
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * String Sanitization Utilities
3
+ *
4
+ * Centralized XSS/SQL injection protection and string sanitization.
5
+ * This is the single source of truth for sanitization patterns.
6
+ */
7
+ import type { SanitizationOptions } from './types';
8
+ /**
9
+ * XSS detection patterns
10
+ */
11
+ export declare const XSS_PATTERNS: {
12
+ readonly scriptTags: RegExp;
13
+ readonly iframeTags: RegExp;
14
+ readonly javascriptProtocol: RegExp;
15
+ readonly vbscriptProtocol: RegExp;
16
+ readonly eventHandlers: RegExp;
17
+ };
18
+ /**
19
+ * SQL injection patterns
20
+ */
21
+ export declare const SQL_PATTERNS: {
22
+ readonly specialChars: RegExp;
23
+ readonly keywords: RegExp;
24
+ };
25
+ /**
26
+ * HTML entity mapping for encoding
27
+ */
28
+ export declare const HTML_ENTITIES: Record<string, string>;
29
+ /**
30
+ * Check if a string contains XSS patterns (for validation without modification)
31
+ */
32
+ export declare function containsXssPatterns(value: string): boolean;
33
+ /**
34
+ * Sanitize string input by removing/encoding dangerous patterns
35
+ */
36
+ export declare function sanitizeString(input: string, options?: SanitizationOptions): string;
37
+ /**
38
+ * Recursively sanitize string fields in an object
39
+ */
40
+ export declare function sanitizeObjectStrings(obj: unknown): unknown;
41
+ //# sourceMappingURL=sanitization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitization.d.ts","sourceRoot":"","sources":["../sanitization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAMhD,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAK1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,MAAM,CA0CR;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CA8B3D"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * String Sanitization Utilities
3
+ *
4
+ * Centralized XSS/SQL injection protection and string sanitization.
5
+ * This is the single source of truth for sanitization patterns.
6
+ */
7
+ /**
8
+ * XSS detection patterns
9
+ */
10
+ export const XSS_PATTERNS = {
11
+ scriptTags: /<script[^>]*>.*?<\/script>/gi,
12
+ iframeTags: /<iframe[^>]*>.*?<\/iframe>/gi,
13
+ javascriptProtocol: /javascript:/gi,
14
+ vbscriptProtocol: /vbscript:/gi,
15
+ eventHandlers: /on\w+=/gi,
16
+ };
17
+ /**
18
+ * SQL injection patterns
19
+ */
20
+ export const SQL_PATTERNS = {
21
+ specialChars: /['";\\]/g,
22
+ keywords: /\b(union|select|insert|update|delete|drop|exec|execute)\b/gi,
23
+ };
24
+ /**
25
+ * HTML entity mapping for encoding
26
+ */
27
+ export const HTML_ENTITIES = {
28
+ '&': '&amp;',
29
+ '<': '&lt;',
30
+ '>': '&gt;',
31
+ '"': '&quot;',
32
+ "'": '&#x27;',
33
+ };
34
+ /**
35
+ * Check if a string contains XSS patterns (for validation without modification)
36
+ */
37
+ export function containsXssPatterns(value) {
38
+ const hasScriptTag = /<script/i.test(value);
39
+ const hasEventHandler = /on\w+=/i.test(value);
40
+ const hasJavascriptProtocol = /javascript:/i.test(value);
41
+ return hasScriptTag || hasEventHandler || hasJavascriptProtocol;
42
+ }
43
+ /**
44
+ * Sanitize string input by removing/encoding dangerous patterns
45
+ */
46
+ export function sanitizeString(input, options = {}) {
47
+ let sanitized = input;
48
+ // Trim whitespace
49
+ if (options.trim !== false) {
50
+ sanitized = sanitized.trim();
51
+ }
52
+ // XSS protection
53
+ if (options.xss !== false) {
54
+ sanitized = sanitized
55
+ .replace(XSS_PATTERNS.scriptTags, '')
56
+ .replace(XSS_PATTERNS.iframeTags, '')
57
+ .replace(XSS_PATTERNS.javascriptProtocol, '')
58
+ .replace(XSS_PATTERNS.vbscriptProtocol, '')
59
+ .replace(XSS_PATTERNS.eventHandlers, '');
60
+ }
61
+ // SQL injection protection
62
+ if (options.sql !== false) {
63
+ sanitized = sanitized
64
+ .replace(SQL_PATTERNS.specialChars, '')
65
+ .replace(SQL_PATTERNS.keywords, '');
66
+ }
67
+ // HTML encoding
68
+ if (options.html) {
69
+ sanitized = sanitized.replace(/[&<>"']/g,
70
+ // eslint-disable-next-line security/detect-object-injection -- char is from known regex match set
71
+ (char) => { var _a; return (_a = HTML_ENTITIES[char]) !== null && _a !== void 0 ? _a : char; });
72
+ }
73
+ // Case transformations
74
+ if (options.lowercase) {
75
+ sanitized = sanitized.toLowerCase();
76
+ }
77
+ else if (options.uppercase) {
78
+ sanitized = sanitized.toUpperCase();
79
+ }
80
+ return sanitized;
81
+ }
82
+ /**
83
+ * Recursively sanitize string fields in an object
84
+ */
85
+ export function sanitizeObjectStrings(obj) {
86
+ if (typeof obj === 'string') {
87
+ return sanitizeString(obj, { xss: true, sql: true, trim: true });
88
+ }
89
+ if (Array.isArray(obj)) {
90
+ return obj.map(sanitizeObjectStrings);
91
+ }
92
+ if (typeof obj === 'object' && obj !== null) {
93
+ const sanitized = {};
94
+ for (const [key, value] of Object.entries(obj)) {
95
+ // Type-safe property assignment for security
96
+ if (typeof key === 'string' &&
97
+ Object.prototype.hasOwnProperty.call(obj, key)) {
98
+ // Use Object.defineProperty to safely assign dynamic keys
99
+ Object.defineProperty(sanitized, key, {
100
+ value: sanitizeObjectStrings(value),
101
+ writable: true,
102
+ enumerable: true,
103
+ configurable: true,
104
+ });
105
+ }
106
+ }
107
+ return sanitized;
108
+ }
109
+ return obj;
110
+ }
111
+ //# sourceMappingURL=sanitization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitization.js","sourceRoot":"","sources":["../sanitization.ts"],"names":[],"mappings":"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"}