@hazeljs/core 0.2.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +522 -0
- package/dist/__tests__/container.test.d.ts +2 -0
- package/dist/__tests__/container.test.d.ts.map +1 -0
- package/dist/__tests__/container.test.js +454 -0
- package/dist/__tests__/decorators.test.d.ts +2 -0
- package/dist/__tests__/decorators.test.d.ts.map +1 -0
- package/dist/__tests__/decorators.test.js +693 -0
- package/dist/__tests__/errors/http.error.test.d.ts +2 -0
- package/dist/__tests__/errors/http.error.test.d.ts.map +1 -0
- package/dist/__tests__/errors/http.error.test.js +117 -0
- package/dist/__tests__/filters/exception-filter.test.d.ts +2 -0
- package/dist/__tests__/filters/exception-filter.test.d.ts.map +1 -0
- package/dist/__tests__/filters/exception-filter.test.js +135 -0
- package/dist/__tests__/filters/http-exception.filter.test.d.ts +2 -0
- package/dist/__tests__/filters/http-exception.filter.test.d.ts.map +1 -0
- package/dist/__tests__/filters/http-exception.filter.test.js +119 -0
- package/dist/__tests__/hazel-app.test.d.ts +2 -0
- package/dist/__tests__/hazel-app.test.d.ts.map +1 -0
- package/dist/__tests__/hazel-app.test.js +682 -0
- package/dist/__tests__/hazel-module.test.d.ts +2 -0
- package/dist/__tests__/hazel-module.test.d.ts.map +1 -0
- package/dist/__tests__/hazel-module.test.js +408 -0
- package/dist/__tests__/hazel-response.test.d.ts +2 -0
- package/dist/__tests__/hazel-response.test.d.ts.map +1 -0
- package/dist/__tests__/hazel-response.test.js +138 -0
- package/dist/__tests__/health.test.d.ts +2 -0
- package/dist/__tests__/health.test.d.ts.map +1 -0
- package/dist/__tests__/health.test.js +147 -0
- package/dist/__tests__/index.test.d.ts +2 -0
- package/dist/__tests__/index.test.d.ts.map +1 -0
- package/dist/__tests__/index.test.js +239 -0
- package/dist/__tests__/interceptors/interceptor.test.d.ts +2 -0
- package/dist/__tests__/interceptors/interceptor.test.d.ts.map +1 -0
- package/dist/__tests__/interceptors/interceptor.test.js +166 -0
- package/dist/__tests__/logger.test.d.ts +2 -0
- package/dist/__tests__/logger.test.d.ts.map +1 -0
- package/dist/__tests__/logger.test.js +141 -0
- package/dist/__tests__/middleware/cors.test.d.ts +2 -0
- package/dist/__tests__/middleware/cors.test.d.ts.map +1 -0
- package/dist/__tests__/middleware/cors.test.js +129 -0
- package/dist/__tests__/middleware/csrf.test.d.ts +2 -0
- package/dist/__tests__/middleware/csrf.test.d.ts.map +1 -0
- package/dist/__tests__/middleware/csrf.test.js +247 -0
- package/dist/__tests__/middleware/global-middleware.test.d.ts +2 -0
- package/dist/__tests__/middleware/global-middleware.test.d.ts.map +1 -0
- package/dist/__tests__/middleware/global-middleware.test.js +259 -0
- package/dist/__tests__/middleware/rate-limit.test.d.ts +2 -0
- package/dist/__tests__/middleware/rate-limit.test.d.ts.map +1 -0
- package/dist/__tests__/middleware/rate-limit.test.js +264 -0
- package/dist/__tests__/middleware/security-headers.test.d.ts +2 -0
- package/dist/__tests__/middleware/security-headers.test.d.ts.map +1 -0
- package/dist/__tests__/middleware/security-headers.test.js +229 -0
- package/dist/__tests__/middleware/timeout.test.d.ts +2 -0
- package/dist/__tests__/middleware/timeout.test.d.ts.map +1 -0
- package/dist/__tests__/middleware/timeout.test.js +132 -0
- package/dist/__tests__/middleware.test.d.ts +2 -0
- package/dist/__tests__/middleware.test.d.ts.map +1 -0
- package/dist/__tests__/middleware.test.js +180 -0
- package/dist/__tests__/pipes/pipe.test.d.ts +2 -0
- package/dist/__tests__/pipes/pipe.test.d.ts.map +1 -0
- package/dist/__tests__/pipes/pipe.test.js +245 -0
- package/dist/__tests__/pipes/validation.pipe.test.d.ts +2 -0
- package/dist/__tests__/pipes/validation.pipe.test.d.ts.map +1 -0
- package/dist/__tests__/pipes/validation.pipe.test.js +297 -0
- package/dist/__tests__/request-parser.test.d.ts +2 -0
- package/dist/__tests__/request-parser.test.d.ts.map +1 -0
- package/dist/__tests__/request-parser.test.js +182 -0
- package/dist/__tests__/router.test.d.ts +2 -0
- package/dist/__tests__/router.test.d.ts.map +1 -0
- package/dist/__tests__/router.test.js +680 -0
- package/dist/__tests__/routing/route-matcher.test.d.ts +2 -0
- package/dist/__tests__/routing/route-matcher.test.d.ts.map +1 -0
- package/dist/__tests__/routing/route-matcher.test.js +219 -0
- package/dist/__tests__/routing/version.decorator.test.d.ts +2 -0
- package/dist/__tests__/routing/version.decorator.test.d.ts.map +1 -0
- package/dist/__tests__/routing/version.decorator.test.js +298 -0
- package/dist/__tests__/service.test.d.ts +2 -0
- package/dist/__tests__/service.test.d.ts.map +1 -0
- package/dist/__tests__/service.test.js +121 -0
- package/dist/__tests__/shutdown.test.d.ts +2 -0
- package/dist/__tests__/shutdown.test.d.ts.map +1 -0
- package/dist/__tests__/shutdown.test.js +250 -0
- package/dist/__tests__/testing/testing.module.test.d.ts +2 -0
- package/dist/__tests__/testing/testing.module.test.d.ts.map +1 -0
- package/dist/__tests__/testing/testing.module.test.js +370 -0
- package/dist/__tests__/upload/file-upload.test.d.ts +2 -0
- package/dist/__tests__/upload/file-upload.test.d.ts.map +1 -0
- package/dist/__tests__/upload/file-upload.test.js +498 -0
- package/dist/__tests__/utils/sanitize.test.d.ts +2 -0
- package/dist/__tests__/utils/sanitize.test.d.ts.map +1 -0
- package/dist/__tests__/utils/sanitize.test.js +291 -0
- package/dist/__tests__/validator.test.d.ts +2 -0
- package/dist/__tests__/validator.test.d.ts.map +1 -0
- package/dist/__tests__/validator.test.js +300 -0
- package/dist/container.d.ts +80 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +271 -0
- package/dist/decorators.d.ts +92 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +343 -0
- package/dist/errors/http.error.d.ts +31 -0
- package/dist/errors/http.error.d.ts.map +1 -0
- package/dist/errors/http.error.js +62 -0
- package/dist/filters/exception-filter.d.ts +39 -0
- package/dist/filters/exception-filter.d.ts.map +1 -0
- package/dist/filters/exception-filter.js +38 -0
- package/dist/filters/http-exception.filter.d.ts +9 -0
- package/dist/filters/http-exception.filter.d.ts.map +1 -0
- package/dist/filters/http-exception.filter.js +42 -0
- package/dist/hazel-app.d.ts +78 -0
- package/dist/hazel-app.d.ts.map +1 -0
- package/dist/hazel-app.js +453 -0
- package/dist/hazel-module.d.ts +20 -0
- package/dist/hazel-module.d.ts.map +1 -0
- package/dist/hazel-module.js +109 -0
- package/dist/hazel-response.d.ts +20 -0
- package/dist/hazel-response.d.ts.map +1 -0
- package/dist/hazel-response.js +68 -0
- package/dist/health.d.ts +73 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +174 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +140 -0
- package/dist/interceptors/interceptor.d.ts +22 -0
- package/dist/interceptors/interceptor.d.ts.map +1 -0
- package/dist/interceptors/interceptor.js +46 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +238 -0
- package/dist/middleware/cors.middleware.d.ts +44 -0
- package/dist/middleware/cors.middleware.d.ts.map +1 -0
- package/dist/middleware/cors.middleware.js +118 -0
- package/dist/middleware/csrf.middleware.d.ts +82 -0
- package/dist/middleware/csrf.middleware.d.ts.map +1 -0
- package/dist/middleware/csrf.middleware.js +183 -0
- package/dist/middleware/global-middleware.d.ts +111 -0
- package/dist/middleware/global-middleware.d.ts.map +1 -0
- package/dist/middleware/global-middleware.js +179 -0
- package/dist/middleware/rate-limit.middleware.d.ts +73 -0
- package/dist/middleware/rate-limit.middleware.d.ts.map +1 -0
- package/dist/middleware/rate-limit.middleware.js +124 -0
- package/dist/middleware/security-headers.middleware.d.ts +76 -0
- package/dist/middleware/security-headers.middleware.d.ts.map +1 -0
- package/dist/middleware/security-headers.middleware.js +123 -0
- package/dist/middleware/timeout.middleware.d.ts +25 -0
- package/dist/middleware/timeout.middleware.d.ts.map +1 -0
- package/dist/middleware/timeout.middleware.js +74 -0
- package/dist/middleware.d.ts +13 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +47 -0
- package/dist/pipes/pipe.d.ts +50 -0
- package/dist/pipes/pipe.d.ts.map +1 -0
- package/dist/pipes/pipe.js +96 -0
- package/dist/pipes/validation.pipe.d.ts +6 -0
- package/dist/pipes/validation.pipe.d.ts.map +1 -0
- package/dist/pipes/validation.pipe.js +61 -0
- package/dist/request-context.d.ts +17 -0
- package/dist/request-context.d.ts.map +1 -0
- package/dist/request-context.js +2 -0
- package/dist/request-parser.d.ts +7 -0
- package/dist/request-parser.d.ts.map +1 -0
- package/dist/request-parser.js +60 -0
- package/dist/router.d.ts +33 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +426 -0
- package/dist/routing/route-matcher.d.ts +39 -0
- package/dist/routing/route-matcher.d.ts.map +1 -0
- package/dist/routing/route-matcher.js +93 -0
- package/dist/routing/version.decorator.d.ts +36 -0
- package/dist/routing/version.decorator.d.ts.map +1 -0
- package/dist/routing/version.decorator.js +89 -0
- package/dist/service.d.ts +9 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +39 -0
- package/dist/shutdown.d.ts +32 -0
- package/dist/shutdown.d.ts.map +1 -0
- package/dist/shutdown.js +109 -0
- package/dist/testing/testing.module.d.ts +83 -0
- package/dist/testing/testing.module.d.ts.map +1 -0
- package/dist/testing/testing.module.js +164 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/upload/file-upload.d.ts +75 -0
- package/dist/upload/file-upload.d.ts.map +1 -0
- package/dist/upload/file-upload.js +261 -0
- package/dist/utils/sanitize.d.ts +45 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +165 -0
- package/dist/validator.d.ts +7 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +119 -0
- package/package.json +65 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Request, Response } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Next function type for middleware chain
|
|
4
|
+
*/
|
|
5
|
+
export type NextFunction = () => Promise<void> | void;
|
|
6
|
+
/**
|
|
7
|
+
* Middleware function type
|
|
8
|
+
*/
|
|
9
|
+
export type MiddlewareFunction = (req: Request, res: Response, next: NextFunction) => Promise<void> | void;
|
|
10
|
+
/**
|
|
11
|
+
* Middleware interface
|
|
12
|
+
*/
|
|
13
|
+
export interface MiddlewareConsumer {
|
|
14
|
+
apply(...middleware: Array<MiddlewareFunction | MiddlewareClass>): MiddlewareConfigProxy;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Middleware class interface
|
|
18
|
+
*/
|
|
19
|
+
export interface MiddlewareClass {
|
|
20
|
+
use(req: Request, res: Response, next: NextFunction): Promise<void> | void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Middleware configuration proxy
|
|
24
|
+
*/
|
|
25
|
+
export interface MiddlewareConfigProxy {
|
|
26
|
+
forRoutes(...routes: Array<string | RouteInfo>): MiddlewareConfigProxy;
|
|
27
|
+
exclude(...routes: Array<string | RouteInfo>): MiddlewareConfigProxy;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Route information
|
|
31
|
+
*/
|
|
32
|
+
export interface RouteInfo {
|
|
33
|
+
path: string;
|
|
34
|
+
method?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Global middleware manager
|
|
38
|
+
*/
|
|
39
|
+
export declare class GlobalMiddlewareManager {
|
|
40
|
+
private middleware;
|
|
41
|
+
/**
|
|
42
|
+
* Add global middleware
|
|
43
|
+
*/
|
|
44
|
+
use(middleware: MiddlewareFunction | MiddlewareClass): void;
|
|
45
|
+
/**
|
|
46
|
+
* Add middleware for specific routes
|
|
47
|
+
*/
|
|
48
|
+
useFor(middleware: MiddlewareFunction | MiddlewareClass, routes: Array<string | RouteInfo>): void;
|
|
49
|
+
/**
|
|
50
|
+
* Add middleware with exclusions
|
|
51
|
+
*/
|
|
52
|
+
useExcept(middleware: MiddlewareFunction | MiddlewareClass, excludedRoutes: Array<string | RouteInfo>): void;
|
|
53
|
+
/**
|
|
54
|
+
* Execute middleware chain for a request
|
|
55
|
+
*/
|
|
56
|
+
execute(req: Request, res: Response): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Get middleware applicable to a request
|
|
59
|
+
*/
|
|
60
|
+
private getApplicableMiddleware;
|
|
61
|
+
/**
|
|
62
|
+
* Check if request matches any route
|
|
63
|
+
*/
|
|
64
|
+
private matchesAnyRoute;
|
|
65
|
+
/**
|
|
66
|
+
* Match path with pattern
|
|
67
|
+
*/
|
|
68
|
+
private matchPath;
|
|
69
|
+
/**
|
|
70
|
+
* Normalize routes to RouteInfo array
|
|
71
|
+
*/
|
|
72
|
+
private normalizeRoutes;
|
|
73
|
+
/**
|
|
74
|
+
* Clear all middleware
|
|
75
|
+
*/
|
|
76
|
+
clear(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Get all registered middleware
|
|
79
|
+
*/
|
|
80
|
+
getMiddleware(): MiddlewareEntry[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Middleware entry
|
|
84
|
+
*/
|
|
85
|
+
interface MiddlewareEntry {
|
|
86
|
+
handler: MiddlewareFunction | MiddlewareClass;
|
|
87
|
+
routes: RouteInfo[];
|
|
88
|
+
excludedRoutes: RouteInfo[];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Built-in CORS middleware
|
|
92
|
+
*/
|
|
93
|
+
export declare class CorsMiddleware implements MiddlewareClass {
|
|
94
|
+
private options;
|
|
95
|
+
constructor(options?: CorsOptions);
|
|
96
|
+
use(req: Request, res: Response, next: NextFunction): void;
|
|
97
|
+
}
|
|
98
|
+
export interface CorsOptions {
|
|
99
|
+
origin?: string;
|
|
100
|
+
methods?: string[];
|
|
101
|
+
allowedHeaders?: string[];
|
|
102
|
+
credentials?: boolean;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Built-in logging middleware
|
|
106
|
+
*/
|
|
107
|
+
export declare class LoggerMiddleware implements MiddlewareClass {
|
|
108
|
+
use(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
109
|
+
}
|
|
110
|
+
export {};
|
|
111
|
+
//# sourceMappingURL=global-middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/global-middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LoggerMiddleware = exports.CorsMiddleware = exports.GlobalMiddlewareManager = void 0;
|
|
7
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
8
|
+
/**
|
|
9
|
+
* Global middleware manager
|
|
10
|
+
*/
|
|
11
|
+
class GlobalMiddlewareManager {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.middleware = [];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Add global middleware
|
|
17
|
+
*/
|
|
18
|
+
use(middleware) {
|
|
19
|
+
logger_1.default.info('Registering global middleware');
|
|
20
|
+
this.middleware.push({
|
|
21
|
+
handler: middleware,
|
|
22
|
+
routes: [],
|
|
23
|
+
excludedRoutes: [],
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Add middleware for specific routes
|
|
28
|
+
*/
|
|
29
|
+
useFor(middleware, routes) {
|
|
30
|
+
logger_1.default.info('Registering route-specific middleware');
|
|
31
|
+
this.middleware.push({
|
|
32
|
+
handler: middleware,
|
|
33
|
+
routes: this.normalizeRoutes(routes),
|
|
34
|
+
excludedRoutes: [],
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Add middleware with exclusions
|
|
39
|
+
*/
|
|
40
|
+
useExcept(middleware, excludedRoutes) {
|
|
41
|
+
logger_1.default.info('Registering middleware with exclusions');
|
|
42
|
+
this.middleware.push({
|
|
43
|
+
handler: middleware,
|
|
44
|
+
routes: [],
|
|
45
|
+
excludedRoutes: this.normalizeRoutes(excludedRoutes),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Execute middleware chain for a request
|
|
50
|
+
*/
|
|
51
|
+
async execute(req, res) {
|
|
52
|
+
const applicableMiddleware = this.getApplicableMiddleware(req);
|
|
53
|
+
let index = 0;
|
|
54
|
+
const next = async () => {
|
|
55
|
+
if (index >= applicableMiddleware.length) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const entry = applicableMiddleware[index++];
|
|
59
|
+
const handler = entry.handler;
|
|
60
|
+
try {
|
|
61
|
+
if (typeof handler === 'function') {
|
|
62
|
+
await handler(req, res, next);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
await handler.use(req, res, next);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
logger_1.default.error('Middleware error:', error);
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
await next();
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get middleware applicable to a request
|
|
77
|
+
*/
|
|
78
|
+
getApplicableMiddleware(req) {
|
|
79
|
+
return this.middleware.filter((entry) => {
|
|
80
|
+
// Check if route is excluded
|
|
81
|
+
if (this.matchesAnyRoute(req, entry.excludedRoutes)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
// If no specific routes, apply to all
|
|
85
|
+
if (entry.routes.length === 0) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
// Check if route matches
|
|
89
|
+
return this.matchesAnyRoute(req, entry.routes);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check if request matches any route
|
|
94
|
+
*/
|
|
95
|
+
matchesAnyRoute(req, routes) {
|
|
96
|
+
const requestPath = req.url?.split('?')[0] || '/';
|
|
97
|
+
const requestMethod = req.method || 'GET';
|
|
98
|
+
return routes.some((route) => {
|
|
99
|
+
const methodMatches = !route.method || route.method === requestMethod;
|
|
100
|
+
const pathMatches = this.matchPath(requestPath, route.path);
|
|
101
|
+
return methodMatches && pathMatches;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Match path with pattern
|
|
106
|
+
*/
|
|
107
|
+
matchPath(path, pattern) {
|
|
108
|
+
// Simple wildcard matching
|
|
109
|
+
if (pattern === '*')
|
|
110
|
+
return true;
|
|
111
|
+
if (pattern.endsWith('*')) {
|
|
112
|
+
const prefix = pattern.slice(0, -1);
|
|
113
|
+
return path.startsWith(prefix);
|
|
114
|
+
}
|
|
115
|
+
return path === pattern;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Normalize routes to RouteInfo array
|
|
119
|
+
*/
|
|
120
|
+
normalizeRoutes(routes) {
|
|
121
|
+
return routes.map((route) => {
|
|
122
|
+
if (typeof route === 'string') {
|
|
123
|
+
return { path: route };
|
|
124
|
+
}
|
|
125
|
+
return route;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Clear all middleware
|
|
130
|
+
*/
|
|
131
|
+
clear() {
|
|
132
|
+
this.middleware = [];
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get all registered middleware
|
|
136
|
+
*/
|
|
137
|
+
getMiddleware() {
|
|
138
|
+
return [...this.middleware];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.GlobalMiddlewareManager = GlobalMiddlewareManager;
|
|
142
|
+
/**
|
|
143
|
+
* Built-in CORS middleware
|
|
144
|
+
*/
|
|
145
|
+
class CorsMiddleware {
|
|
146
|
+
constructor(options = {}) {
|
|
147
|
+
this.options = options;
|
|
148
|
+
}
|
|
149
|
+
use(req, res, next) {
|
|
150
|
+
const origin = this.options.origin || '*';
|
|
151
|
+
const methods = this.options.methods || ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'];
|
|
152
|
+
const headers = this.options.allowedHeaders || ['Content-Type', 'Authorization'];
|
|
153
|
+
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
154
|
+
res.setHeader('Access-Control-Allow-Methods', methods.join(', '));
|
|
155
|
+
res.setHeader('Access-Control-Allow-Headers', headers.join(', '));
|
|
156
|
+
if (this.options.credentials) {
|
|
157
|
+
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
158
|
+
}
|
|
159
|
+
if (req.method === 'OPTIONS') {
|
|
160
|
+
res.status(204).end();
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
next();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
exports.CorsMiddleware = CorsMiddleware;
|
|
167
|
+
/**
|
|
168
|
+
* Built-in logging middleware
|
|
169
|
+
*/
|
|
170
|
+
class LoggerMiddleware {
|
|
171
|
+
async use(req, res, next) {
|
|
172
|
+
const start = Date.now();
|
|
173
|
+
logger_1.default.info(`→ ${req.method} ${req.url}`);
|
|
174
|
+
await next();
|
|
175
|
+
const duration = Date.now() - start;
|
|
176
|
+
logger_1.default.info(`← ${req.method} ${req.url} ${duration}ms`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.LoggerMiddleware = LoggerMiddleware;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Request, Response } from '../types';
|
|
2
|
+
import { MiddlewareClass, NextFunction } from './global-middleware';
|
|
3
|
+
/**
|
|
4
|
+
* Rate limit storage interface
|
|
5
|
+
*/
|
|
6
|
+
interface RateLimitStore {
|
|
7
|
+
get(key: string): Promise<number | null>;
|
|
8
|
+
set(key: string, value: number, ttl: number): Promise<void>;
|
|
9
|
+
increment(key: string, ttl: number): Promise<number>;
|
|
10
|
+
reset(key: string): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Rate limit options
|
|
14
|
+
*/
|
|
15
|
+
export interface RateLimitOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Maximum number of requests
|
|
18
|
+
*/
|
|
19
|
+
max: number;
|
|
20
|
+
/**
|
|
21
|
+
* Time window in seconds
|
|
22
|
+
*/
|
|
23
|
+
windowMs: number;
|
|
24
|
+
/**
|
|
25
|
+
* Custom key generator function
|
|
26
|
+
*/
|
|
27
|
+
keyGenerator?: (req: Request) => string;
|
|
28
|
+
/**
|
|
29
|
+
* Custom store (default: in-memory)
|
|
30
|
+
*/
|
|
31
|
+
store?: RateLimitStore;
|
|
32
|
+
/**
|
|
33
|
+
* Skip successful requests
|
|
34
|
+
*/
|
|
35
|
+
skipSuccessfulRequests?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Skip failed requests
|
|
38
|
+
*/
|
|
39
|
+
skipFailedRequests?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Custom error message
|
|
42
|
+
*/
|
|
43
|
+
message?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Custom error status code
|
|
46
|
+
*/
|
|
47
|
+
statusCode?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Standard rate limit headers
|
|
50
|
+
*/
|
|
51
|
+
standardHeaders?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Legacy rate limit headers
|
|
54
|
+
*/
|
|
55
|
+
legacyHeaders?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Rate Limiting Middleware
|
|
59
|
+
* Prevents abuse by limiting the number of requests from a single IP
|
|
60
|
+
*/
|
|
61
|
+
export declare class RateLimitMiddleware implements MiddlewareClass {
|
|
62
|
+
private options;
|
|
63
|
+
private store;
|
|
64
|
+
private cleanupInterval;
|
|
65
|
+
constructor(options: RateLimitOptions);
|
|
66
|
+
use(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Cleanup resources
|
|
69
|
+
*/
|
|
70
|
+
destroy(): void;
|
|
71
|
+
}
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=rate-limit.middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/rate-limit.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAIpE;;GAEG;AACH,UAAU,cAAc;IACtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AA0DD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IAExC;;OAEG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC;IAEvB;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IAI7C,OAAO,CAAC,OAAO;IAH3B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,eAAe,CAA+B;gBAElC,OAAO,EAAE,gBAAgB;IA2BvC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCzE;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RateLimitMiddleware = void 0;
|
|
7
|
+
const http_error_1 = require("../errors/http.error");
|
|
8
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
9
|
+
/**
|
|
10
|
+
* In-memory rate limit store
|
|
11
|
+
*/
|
|
12
|
+
class MemoryStore {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.store = new Map();
|
|
15
|
+
}
|
|
16
|
+
async get(key) {
|
|
17
|
+
const entry = this.store.get(key);
|
|
18
|
+
if (!entry)
|
|
19
|
+
return null;
|
|
20
|
+
if (Date.now() > entry.resetTime) {
|
|
21
|
+
this.store.delete(key);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
return entry.count;
|
|
25
|
+
}
|
|
26
|
+
async set(key, value, ttl) {
|
|
27
|
+
this.store.set(key, {
|
|
28
|
+
count: value,
|
|
29
|
+
resetTime: Date.now() + ttl * 1000,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async increment(key, ttl) {
|
|
33
|
+
const entry = this.store.get(key);
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
if (!entry || now > entry.resetTime) {
|
|
36
|
+
await this.set(key, 1, ttl);
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
entry.count++;
|
|
40
|
+
this.store.set(key, entry);
|
|
41
|
+
return entry.count;
|
|
42
|
+
}
|
|
43
|
+
async reset(key) {
|
|
44
|
+
this.store.delete(key);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Clean up expired entries
|
|
48
|
+
*/
|
|
49
|
+
cleanup() {
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
for (const [key, entry] of this.store.entries()) {
|
|
52
|
+
if (now > entry.resetTime) {
|
|
53
|
+
this.store.delete(key);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Rate Limiting Middleware
|
|
60
|
+
* Prevents abuse by limiting the number of requests from a single IP
|
|
61
|
+
*/
|
|
62
|
+
class RateLimitMiddleware {
|
|
63
|
+
constructor(options) {
|
|
64
|
+
this.options = options;
|
|
65
|
+
this.cleanupInterval = null;
|
|
66
|
+
this.store = options.store || new MemoryStore();
|
|
67
|
+
// Set defaults
|
|
68
|
+
this.options = {
|
|
69
|
+
keyGenerator: (req) => {
|
|
70
|
+
const forwarded = req.headers?.['x-forwarded-for'];
|
|
71
|
+
const ip = forwarded
|
|
72
|
+
? (Array.isArray(forwarded) ? forwarded[0] : forwarded.split(',')[0].trim())
|
|
73
|
+
: req.socket?.remoteAddress || 'unknown';
|
|
74
|
+
return ip;
|
|
75
|
+
},
|
|
76
|
+
message: 'Too many requests, please try again later.',
|
|
77
|
+
statusCode: 429,
|
|
78
|
+
standardHeaders: true,
|
|
79
|
+
legacyHeaders: true,
|
|
80
|
+
...options,
|
|
81
|
+
};
|
|
82
|
+
// Cleanup expired entries every minute
|
|
83
|
+
if (this.store instanceof MemoryStore) {
|
|
84
|
+
this.cleanupInterval = setInterval(() => {
|
|
85
|
+
this.store.cleanup();
|
|
86
|
+
}, 60000);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async use(req, res, next) {
|
|
90
|
+
const key = this.options.keyGenerator(req);
|
|
91
|
+
const count = await this.store.increment(key, this.options.windowMs);
|
|
92
|
+
// Set rate limit headers
|
|
93
|
+
if (this.options.standardHeaders) {
|
|
94
|
+
res.setHeader('RateLimit-Limit', this.options.max.toString());
|
|
95
|
+
res.setHeader('RateLimit-Remaining', Math.max(0, this.options.max - count).toString());
|
|
96
|
+
res.setHeader('RateLimit-Reset', new Date(Date.now() + this.options.windowMs * 1000).toISOString());
|
|
97
|
+
}
|
|
98
|
+
if (this.options.legacyHeaders) {
|
|
99
|
+
res.setHeader('X-RateLimit-Limit', this.options.max.toString());
|
|
100
|
+
res.setHeader('X-RateLimit-Remaining', Math.max(0, this.options.max - count).toString());
|
|
101
|
+
res.setHeader('X-RateLimit-Reset', new Date(Date.now() + this.options.windowMs * 1000).toISOString());
|
|
102
|
+
}
|
|
103
|
+
// Check if limit exceeded
|
|
104
|
+
if (count > this.options.max) {
|
|
105
|
+
logger_1.default.warn(`Rate limit exceeded for ${key}: ${count}/${this.options.max}`);
|
|
106
|
+
throw new http_error_1.HttpError(this.options.statusCode, this.options.message);
|
|
107
|
+
}
|
|
108
|
+
await next();
|
|
109
|
+
// Handle skip options
|
|
110
|
+
// Note: Response statusCode is set via res.status() and checked via res.writeHead
|
|
111
|
+
// For now, we'll skip this check as Response interface doesn't expose statusCode directly
|
|
112
|
+
// In a real implementation, you'd track the status in a response interceptor
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Cleanup resources
|
|
116
|
+
*/
|
|
117
|
+
destroy() {
|
|
118
|
+
if (this.cleanupInterval) {
|
|
119
|
+
clearInterval(this.cleanupInterval);
|
|
120
|
+
this.cleanupInterval = null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.RateLimitMiddleware = RateLimitMiddleware;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Request, Response } from '../types';
|
|
2
|
+
import { MiddlewareClass, NextFunction } from './global-middleware';
|
|
3
|
+
/**
|
|
4
|
+
* Security headers configuration
|
|
5
|
+
*/
|
|
6
|
+
export interface SecurityHeadersOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Enable X-Content-Type-Options header
|
|
9
|
+
* Prevents MIME type sniffing
|
|
10
|
+
*/
|
|
11
|
+
noSniff?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Enable X-Frame-Options header
|
|
14
|
+
* Prevents clickjacking attacks
|
|
15
|
+
*/
|
|
16
|
+
frameOptions?: 'DENY' | 'SAMEORIGIN' | string;
|
|
17
|
+
/**
|
|
18
|
+
* Enable X-XSS-Protection header
|
|
19
|
+
* Enables browser XSS filter
|
|
20
|
+
*/
|
|
21
|
+
xssProtection?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Enable Strict-Transport-Security (HSTS) header
|
|
24
|
+
* Forces HTTPS connections
|
|
25
|
+
*/
|
|
26
|
+
hsts?: {
|
|
27
|
+
maxAge?: number;
|
|
28
|
+
includeSubDomains?: boolean;
|
|
29
|
+
preload?: boolean;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Enable Content-Security-Policy header
|
|
33
|
+
* Controls resource loading
|
|
34
|
+
*/
|
|
35
|
+
contentSecurityPolicy?: string | {
|
|
36
|
+
defaultSrc?: string[];
|
|
37
|
+
scriptSrc?: string[];
|
|
38
|
+
styleSrc?: string[];
|
|
39
|
+
imgSrc?: string[];
|
|
40
|
+
connectSrc?: string[];
|
|
41
|
+
fontSrc?: string[];
|
|
42
|
+
objectSrc?: string[];
|
|
43
|
+
mediaSrc?: string[];
|
|
44
|
+
frameSrc?: string[];
|
|
45
|
+
baseUri?: string[];
|
|
46
|
+
formAction?: string[];
|
|
47
|
+
frameAncestors?: string[];
|
|
48
|
+
upgradeInsecureRequests?: boolean;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Enable Referrer-Policy header
|
|
52
|
+
* Controls referrer information
|
|
53
|
+
*/
|
|
54
|
+
referrerPolicy?: 'no-referrer' | 'no-referrer-when-downgrade' | 'origin' | 'origin-when-cross-origin' | 'same-origin' | 'strict-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url';
|
|
55
|
+
/**
|
|
56
|
+
* Enable Permissions-Policy header
|
|
57
|
+
* Controls browser features
|
|
58
|
+
*/
|
|
59
|
+
permissionsPolicy?: Record<string, string[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Enable X-Powered-By removal
|
|
62
|
+
* Hides framework information
|
|
63
|
+
*/
|
|
64
|
+
hidePoweredBy?: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Security Headers Middleware
|
|
68
|
+
* Adds security headers to HTTP responses
|
|
69
|
+
*/
|
|
70
|
+
export declare class SecurityHeadersMiddleware implements MiddlewareClass {
|
|
71
|
+
private options;
|
|
72
|
+
constructor(options?: SecurityHeadersOptions);
|
|
73
|
+
use(req: Request, res: Response, next: NextFunction): void;
|
|
74
|
+
private buildCSP;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=security-headers.middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-headers.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/security-headers.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC;IAE9C;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IAEF;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,GAAG;QAC/B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,uBAAuB,CAAC,EAAE,OAAO,CAAC;KACnC,CAAC;IAEF;;;OAGG;IACH,cAAc,CAAC,EAAE,aAAa,GAAG,4BAA4B,GAAG,QAAQ,GAAG,0BAA0B,GAAG,aAAa,GAAG,eAAe,GAAG,iCAAiC,GAAG,YAAY,CAAC;IAE3L;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE7C;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,eAAe;IACnD,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE,sBAA2B;IAgBxD,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IA+D1D,OAAO,CAAC,QAAQ;CAiDjB"}
|