@xbg.solutions/backend-core 1.0.0
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/lib/core/src/app.d.ts +28 -0
- package/lib/core/src/app.d.ts.map +1 -0
- package/lib/core/src/app.js +188 -0
- package/lib/core/src/app.js.map +1 -0
- package/lib/core/src/base/BaseController.d.ts +108 -0
- package/lib/core/src/base/BaseController.d.ts.map +1 -0
- package/lib/core/src/base/BaseController.js +307 -0
- package/lib/core/src/base/BaseController.js.map +1 -0
- package/lib/core/src/base/BaseEntity.d.ts +92 -0
- package/lib/core/src/base/BaseEntity.d.ts.map +1 -0
- package/lib/core/src/base/BaseEntity.js +143 -0
- package/lib/core/src/base/BaseEntity.js.map +1 -0
- package/lib/core/src/base/BaseRepository.d.ts +124 -0
- package/lib/core/src/base/BaseRepository.d.ts.map +1 -0
- package/lib/core/src/base/BaseRepository.js +414 -0
- package/lib/core/src/base/BaseRepository.js.map +1 -0
- package/lib/core/src/base/BaseService.d.ts +89 -0
- package/lib/core/src/base/BaseService.d.ts.map +1 -0
- package/lib/core/src/base/BaseService.js +342 -0
- package/lib/core/src/base/BaseService.js.map +1 -0
- package/lib/core/src/base/index.d.ts +8 -0
- package/lib/core/src/base/index.d.ts.map +1 -0
- package/lib/core/src/base/index.js +24 -0
- package/lib/core/src/base/index.js.map +1 -0
- package/lib/core/src/config/app.config.d.ts +70 -0
- package/lib/core/src/config/app.config.d.ts.map +1 -0
- package/lib/core/src/config/app.config.js +106 -0
- package/lib/core/src/config/app.config.js.map +1 -0
- package/lib/core/src/config/auth.config.d.ts +54 -0
- package/lib/core/src/config/auth.config.d.ts.map +1 -0
- package/lib/core/src/config/auth.config.js +88 -0
- package/lib/core/src/config/auth.config.js.map +1 -0
- package/lib/core/src/config/cache.config.d.ts +47 -0
- package/lib/core/src/config/cache.config.d.ts.map +1 -0
- package/lib/core/src/config/cache.config.js +225 -0
- package/lib/core/src/config/cache.config.js.map +1 -0
- package/lib/core/src/config/communications.config.d.ts +175 -0
- package/lib/core/src/config/communications.config.d.ts.map +1 -0
- package/lib/core/src/config/communications.config.js +219 -0
- package/lib/core/src/config/communications.config.js.map +1 -0
- package/lib/core/src/config/database.config.d.ts +68 -0
- package/lib/core/src/config/database.config.d.ts.map +1 -0
- package/lib/core/src/config/database.config.js +95 -0
- package/lib/core/src/config/database.config.js.map +1 -0
- package/lib/core/src/config/firebase-event-mapping.config.d.ts +41 -0
- package/lib/core/src/config/firebase-event-mapping.config.d.ts.map +1 -0
- package/lib/core/src/config/firebase-event-mapping.config.js +180 -0
- package/lib/core/src/config/firebase-event-mapping.config.js.map +1 -0
- package/lib/core/src/config/firestore.config.d.ts +61 -0
- package/lib/core/src/config/firestore.config.d.ts.map +1 -0
- package/lib/core/src/config/firestore.config.js +74 -0
- package/lib/core/src/config/firestore.config.js.map +1 -0
- package/lib/core/src/config/index.d.ts +15 -0
- package/lib/core/src/config/index.d.ts.map +1 -0
- package/lib/core/src/config/index.js +41 -0
- package/lib/core/src/config/index.js.map +1 -0
- package/lib/core/src/config/maps.config.d.ts +31 -0
- package/lib/core/src/config/maps.config.d.ts.map +1 -0
- package/lib/core/src/config/maps.config.js +50 -0
- package/lib/core/src/config/maps.config.js.map +1 -0
- package/lib/core/src/config/middleware.config.d.ts +57 -0
- package/lib/core/src/config/middleware.config.d.ts.map +1 -0
- package/lib/core/src/config/middleware.config.js +68 -0
- package/lib/core/src/config/middleware.config.js.map +1 -0
- package/lib/core/src/config/tokens.config.d.ts +53 -0
- package/lib/core/src/config/tokens.config.d.ts.map +1 -0
- package/lib/core/src/config/tokens.config.js +129 -0
- package/lib/core/src/config/tokens.config.js.map +1 -0
- package/lib/core/src/generator/generator.d.ts +38 -0
- package/lib/core/src/generator/generator.d.ts.map +1 -0
- package/lib/core/src/generator/generator.js +159 -0
- package/lib/core/src/generator/generator.js.map +1 -0
- package/lib/core/src/generator/index.d.ts +7 -0
- package/lib/core/src/generator/index.d.ts.map +1 -0
- package/lib/core/src/generator/index.js +23 -0
- package/lib/core/src/generator/index.js.map +1 -0
- package/lib/core/src/generator/parser.d.ts +10 -0
- package/lib/core/src/generator/parser.d.ts.map +1 -0
- package/lib/core/src/generator/parser.js +197 -0
- package/lib/core/src/generator/parser.js.map +1 -0
- package/lib/core/src/generator/types.d.ts +112 -0
- package/lib/core/src/generator/types.d.ts.map +1 -0
- package/lib/core/src/generator/types.js +7 -0
- package/lib/core/src/generator/types.js.map +1 -0
- package/lib/core/src/index.d.ts +19 -0
- package/lib/core/src/index.d.ts.map +1 -0
- package/lib/core/src/index.js +46 -0
- package/lib/core/src/index.js.map +1 -0
- package/lib/core/src/middleware/auth.middleware.d.ts +57 -0
- package/lib/core/src/middleware/auth.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/auth.middleware.js +256 -0
- package/lib/core/src/middleware/auth.middleware.js.map +1 -0
- package/lib/core/src/middleware/cors.middleware.d.ts +13 -0
- package/lib/core/src/middleware/cors.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/cors.middleware.js +50 -0
- package/lib/core/src/middleware/cors.middleware.js.map +1 -0
- package/lib/core/src/middleware/error.middleware.d.ts +46 -0
- package/lib/core/src/middleware/error.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/error.middleware.js +174 -0
- package/lib/core/src/middleware/error.middleware.js.map +1 -0
- package/lib/core/src/middleware/index.d.ts +11 -0
- package/lib/core/src/middleware/index.d.ts.map +1 -0
- package/lib/core/src/middleware/index.js +27 -0
- package/lib/core/src/middleware/index.js.map +1 -0
- package/lib/core/src/middleware/logging.middleware.d.ts +10 -0
- package/lib/core/src/middleware/logging.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/logging.middleware.js +87 -0
- package/lib/core/src/middleware/logging.middleware.js.map +1 -0
- package/lib/core/src/middleware/rateLimit.middleware.d.ts +26 -0
- package/lib/core/src/middleware/rateLimit.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/rateLimit.middleware.js +105 -0
- package/lib/core/src/middleware/rateLimit.middleware.js.map +1 -0
- package/lib/core/src/middleware/requestId.middleware.d.ts +11 -0
- package/lib/core/src/middleware/requestId.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/requestId.middleware.js +26 -0
- package/lib/core/src/middleware/requestId.middleware.js.map +1 -0
- package/lib/core/src/middleware/validation.middleware.d.ts +25 -0
- package/lib/core/src/middleware/validation.middleware.d.ts.map +1 -0
- package/lib/core/src/middleware/validation.middleware.js +133 -0
- package/lib/core/src/middleware/validation.middleware.js.map +1 -0
- package/lib/core/src/types/errors.d.ts +119 -0
- package/lib/core/src/types/errors.d.ts.map +1 -0
- package/lib/core/src/types/errors.js +210 -0
- package/lib/core/src/types/errors.js.map +1 -0
- package/lib/utils-cache-connector/src/cache-connector.d.ts +139 -0
- package/lib/utils-cache-connector/src/cache-connector.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/cache-connector.js +277 -0
- package/lib/utils-cache-connector/src/cache-connector.js.map +1 -0
- package/lib/utils-cache-connector/src/index.d.ts +52 -0
- package/lib/utils-cache-connector/src/index.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/index.js +103 -0
- package/lib/utils-cache-connector/src/index.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/base-cache-provider.d.ts +95 -0
- package/lib/utils-cache-connector/src/providers/base-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/base-cache-provider.js +120 -0
- package/lib/utils-cache-connector/src/providers/base-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/firestore-cache-provider.d.ts +58 -0
- package/lib/utils-cache-connector/src/providers/firestore-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/firestore-cache-provider.js +418 -0
- package/lib/utils-cache-connector/src/providers/firestore-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/memory-cache-provider.d.ts +57 -0
- package/lib/utils-cache-connector/src/providers/memory-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/memory-cache-provider.js +217 -0
- package/lib/utils-cache-connector/src/providers/memory-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/noop-cache-provider.d.ts +21 -0
- package/lib/utils-cache-connector/src/providers/noop-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/noop-cache-provider.js +42 -0
- package/lib/utils-cache-connector/src/providers/noop-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/providers/redis-cache-provider.d.ts +64 -0
- package/lib/utils-cache-connector/src/providers/redis-cache-provider.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/providers/redis-cache-provider.js +414 -0
- package/lib/utils-cache-connector/src/providers/redis-cache-provider.js.map +1 -0
- package/lib/utils-cache-connector/src/types.d.ts +342 -0
- package/lib/utils-cache-connector/src/types.d.ts.map +1 -0
- package/lib/utils-cache-connector/src/types.js +8 -0
- package/lib/utils-cache-connector/src/types.js.map +1 -0
- package/lib/utils-events/src/event-bus.d.ts +42 -0
- package/lib/utils-events/src/event-bus.d.ts.map +1 -0
- package/lib/utils-events/src/event-bus.js +93 -0
- package/lib/utils-events/src/event-bus.js.map +1 -0
- package/lib/utils-events/src/event-types.d.ts +146 -0
- package/lib/utils-events/src/event-types.d.ts.map +1 -0
- package/lib/utils-events/src/event-types.js +49 -0
- package/lib/utils-events/src/event-types.js.map +1 -0
- package/lib/utils-events/src/index.d.ts +7 -0
- package/lib/utils-events/src/index.d.ts.map +1 -0
- package/lib/utils-events/src/index.js +11 -0
- package/lib/utils-events/src/index.js.map +1 -0
- package/lib/utils-logger/src/index.d.ts +12 -0
- package/lib/utils-logger/src/index.d.ts.map +1 -0
- package/lib/utils-logger/src/index.js +29 -0
- package/lib/utils-logger/src/index.js.map +1 -0
- package/lib/utils-logger/src/logger-types.d.ts +32 -0
- package/lib/utils-logger/src/logger-types.d.ts.map +1 -0
- package/lib/utils-logger/src/logger-types.js +17 -0
- package/lib/utils-logger/src/logger-types.js.map +1 -0
- package/lib/utils-logger/src/logger.d.ts +42 -0
- package/lib/utils-logger/src/logger.d.ts.map +1 -0
- package/lib/utils-logger/src/logger.js +123 -0
- package/lib/utils-logger/src/logger.js.map +1 -0
- package/package.json +49 -0
- package/src/templates/controller.hbs +48 -0
- package/src/templates/entity.hbs +80 -0
- package/src/templates/repository.hbs +56 -0
- package/src/templates/service.hbs +108 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Error Handling Middleware
|
|
4
|
+
* Global error handler and custom error classes
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ConflictError = exports.ForbiddenError = exports.UnauthorizedError = exports.ValidationError = exports.NotFoundError = exports.AppError = void 0;
|
|
8
|
+
exports.errorHandler = errorHandler;
|
|
9
|
+
exports.notFoundHandler = notFoundHandler;
|
|
10
|
+
exports.asyncHandler = asyncHandler;
|
|
11
|
+
const utils_logger_1 = require("@xbg/utils-logger");
|
|
12
|
+
const app_config_1 = require("../config/app.config");
|
|
13
|
+
/**
|
|
14
|
+
* Custom application errors
|
|
15
|
+
*/
|
|
16
|
+
class AppError extends Error {
|
|
17
|
+
constructor(code, message, statusCode = 500, details) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.code = code;
|
|
20
|
+
this.message = message;
|
|
21
|
+
this.statusCode = statusCode;
|
|
22
|
+
this.details = details;
|
|
23
|
+
this.name = 'AppError';
|
|
24
|
+
Error.captureStackTrace(this, this.constructor);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.AppError = AppError;
|
|
28
|
+
class NotFoundError extends AppError {
|
|
29
|
+
constructor(resource, id) {
|
|
30
|
+
super('NOT_FOUND', `${resource} not found${id ? `: ${id}` : ''}`, 404, { resource, id });
|
|
31
|
+
this.name = 'NotFoundError';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.NotFoundError = NotFoundError;
|
|
35
|
+
class ValidationError extends AppError {
|
|
36
|
+
constructor(message, details) {
|
|
37
|
+
super('VALIDATION_ERROR', message, 400, details);
|
|
38
|
+
this.name = 'ValidationError';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.ValidationError = ValidationError;
|
|
42
|
+
class UnauthorizedError extends AppError {
|
|
43
|
+
constructor(message = 'Authentication required') {
|
|
44
|
+
super('UNAUTHORIZED', message, 401);
|
|
45
|
+
this.name = 'UnauthorizedError';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.UnauthorizedError = UnauthorizedError;
|
|
49
|
+
class ForbiddenError extends AppError {
|
|
50
|
+
constructor(message = 'Access denied') {
|
|
51
|
+
super('FORBIDDEN', message, 403);
|
|
52
|
+
this.name = 'ForbiddenError';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.ForbiddenError = ForbiddenError;
|
|
56
|
+
class ConflictError extends AppError {
|
|
57
|
+
constructor(message, details) {
|
|
58
|
+
super('CONFLICT', message, 409, details);
|
|
59
|
+
this.name = 'ConflictError';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.ConflictError = ConflictError;
|
|
63
|
+
/**
|
|
64
|
+
* Global error handling middleware
|
|
65
|
+
* Must be registered last in middleware chain
|
|
66
|
+
*/
|
|
67
|
+
function errorHandler() {
|
|
68
|
+
return (err, req, res, _next) => {
|
|
69
|
+
const requestId = req.headers['x-request-id'] || 'unknown';
|
|
70
|
+
// Log error
|
|
71
|
+
utils_logger_1.logger.error('Request error', err, {
|
|
72
|
+
requestId,
|
|
73
|
+
path: req.path,
|
|
74
|
+
method: req.method,
|
|
75
|
+
});
|
|
76
|
+
// Handle known AppErrors
|
|
77
|
+
if (err instanceof AppError) {
|
|
78
|
+
return res.status(err.statusCode).json({
|
|
79
|
+
success: false,
|
|
80
|
+
error: {
|
|
81
|
+
code: err.code,
|
|
82
|
+
message: err.message,
|
|
83
|
+
details: err.details,
|
|
84
|
+
},
|
|
85
|
+
metadata: {
|
|
86
|
+
requestId,
|
|
87
|
+
timestamp: new Date().toISOString(),
|
|
88
|
+
version: '1.0.0',
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// Handle validation errors from express-validator
|
|
93
|
+
if (err.name === 'ValidationError') {
|
|
94
|
+
return res.status(400).json({
|
|
95
|
+
success: false,
|
|
96
|
+
error: {
|
|
97
|
+
code: 'VALIDATION_ERROR',
|
|
98
|
+
message: err.message,
|
|
99
|
+
},
|
|
100
|
+
metadata: {
|
|
101
|
+
requestId,
|
|
102
|
+
timestamp: new Date().toISOString(),
|
|
103
|
+
version: '1.0.0',
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// Handle Firestore errors
|
|
108
|
+
if (err.message.includes('PERMISSION_DENIED')) {
|
|
109
|
+
return res.status(403).json({
|
|
110
|
+
success: false,
|
|
111
|
+
error: {
|
|
112
|
+
code: 'PERMISSION_DENIED',
|
|
113
|
+
message: 'Database permission denied',
|
|
114
|
+
},
|
|
115
|
+
metadata: {
|
|
116
|
+
requestId,
|
|
117
|
+
timestamp: new Date().toISOString(),
|
|
118
|
+
version: '1.0.0',
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// Default to 500 Internal Server Error
|
|
123
|
+
const isDevelopment = app_config_1.APP_CONFIG.app.environment === 'development';
|
|
124
|
+
return res.status(500).json({
|
|
125
|
+
success: false,
|
|
126
|
+
error: {
|
|
127
|
+
code: 'INTERNAL_ERROR',
|
|
128
|
+
message: isDevelopment ? err.message : 'An unexpected error occurred',
|
|
129
|
+
details: isDevelopment ? { stack: err.stack } : undefined,
|
|
130
|
+
},
|
|
131
|
+
metadata: {
|
|
132
|
+
requestId,
|
|
133
|
+
timestamp: new Date().toISOString(),
|
|
134
|
+
version: '1.0.0',
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* 404 Not Found handler
|
|
141
|
+
* For unmatched routes
|
|
142
|
+
*/
|
|
143
|
+
function notFoundHandler() {
|
|
144
|
+
return (req, res) => {
|
|
145
|
+
const requestId = req.headers['x-request-id'] || 'unknown';
|
|
146
|
+
utils_logger_1.logger.warn('Route not found', {
|
|
147
|
+
requestId,
|
|
148
|
+
path: req.path,
|
|
149
|
+
method: req.method,
|
|
150
|
+
});
|
|
151
|
+
res.status(404).json({
|
|
152
|
+
success: false,
|
|
153
|
+
error: {
|
|
154
|
+
code: 'NOT_FOUND',
|
|
155
|
+
message: `Route not found: ${req.method} ${req.path}`,
|
|
156
|
+
},
|
|
157
|
+
metadata: {
|
|
158
|
+
requestId,
|
|
159
|
+
timestamp: new Date().toISOString(),
|
|
160
|
+
version: '1.0.0',
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Async handler wrapper
|
|
167
|
+
* Catches async errors and passes to error middleware
|
|
168
|
+
*/
|
|
169
|
+
function asyncHandler(fn) {
|
|
170
|
+
return (req, res, next) => {
|
|
171
|
+
Promise.resolve(fn(req, res, next)).catch(next);
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=error.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.middleware.js","sourceRoot":"","sources":["../../../../src/middleware/error.middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware barrel export
|
|
3
|
+
*/
|
|
4
|
+
export * from './auth.middleware';
|
|
5
|
+
export * from './cors.middleware';
|
|
6
|
+
export * from './rateLimit.middleware';
|
|
7
|
+
export * from './validation.middleware';
|
|
8
|
+
export * from './error.middleware';
|
|
9
|
+
export * from './requestId.middleware';
|
|
10
|
+
export * from './logging.middleware';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/middleware/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Middleware barrel export
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./auth.middleware"), exports);
|
|
21
|
+
__exportStar(require("./cors.middleware"), exports);
|
|
22
|
+
__exportStar(require("./rateLimit.middleware"), exports);
|
|
23
|
+
__exportStar(require("./validation.middleware"), exports);
|
|
24
|
+
__exportStar(require("./error.middleware"), exports);
|
|
25
|
+
__exportStar(require("./requestId.middleware"), exports);
|
|
26
|
+
__exportStar(require("./logging.middleware"), exports);
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/middleware/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,oDAAkC;AAClC,oDAAkC;AAClC,yDAAuC;AACvC,0DAAwC;AACxC,qDAAmC;AACnC,yDAAuC;AACvC,uDAAqC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request Logging Middleware
|
|
3
|
+
* Logs all HTTP requests with configurable detail level
|
|
4
|
+
*/
|
|
5
|
+
import { Request, Response, NextFunction } from 'express';
|
|
6
|
+
/**
|
|
7
|
+
* Request logging middleware
|
|
8
|
+
*/
|
|
9
|
+
export declare function requestLoggingMiddleware(): (req: Request, res: Response, next: NextFunction) => void;
|
|
10
|
+
//# sourceMappingURL=logging.middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.middleware.d.ts","sourceRoot":"","sources":["../../../../src/middleware/logging.middleware.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI1D;;GAEG;AACH,wBAAgB,wBAAwB,KAC9B,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UA0CxD"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Request Logging Middleware
|
|
4
|
+
* Logs all HTTP requests with configurable detail level
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.requestLoggingMiddleware = requestLoggingMiddleware;
|
|
8
|
+
const utils_logger_1 = require("@xbg/utils-logger");
|
|
9
|
+
const middleware_config_1 = require("../config/middleware.config");
|
|
10
|
+
/**
|
|
11
|
+
* Request logging middleware
|
|
12
|
+
*/
|
|
13
|
+
function requestLoggingMiddleware() {
|
|
14
|
+
return (req, res, next) => {
|
|
15
|
+
const startTime = Date.now();
|
|
16
|
+
const requestId = req.headers['x-request-id'] || 'unknown';
|
|
17
|
+
// Log request
|
|
18
|
+
const logData = {
|
|
19
|
+
requestId,
|
|
20
|
+
method: req.method,
|
|
21
|
+
path: req.path,
|
|
22
|
+
query: req.query,
|
|
23
|
+
ip: req.ip,
|
|
24
|
+
userAgent: req.headers['user-agent'],
|
|
25
|
+
};
|
|
26
|
+
if (middleware_config_1.MIDDLEWARE_CONFIG.logging.logHeaders) {
|
|
27
|
+
logData.headers = filterSensitiveHeaders(req.headers);
|
|
28
|
+
}
|
|
29
|
+
if (middleware_config_1.MIDDLEWARE_CONFIG.logging.logBody && req.body) {
|
|
30
|
+
logData.body = filterSensitiveData(req.body);
|
|
31
|
+
}
|
|
32
|
+
utils_logger_1.logger.info('Incoming request', logData);
|
|
33
|
+
// Log response
|
|
34
|
+
const originalSend = res.send;
|
|
35
|
+
res.send = function (data) {
|
|
36
|
+
const duration = Date.now() - startTime;
|
|
37
|
+
utils_logger_1.logger.info('Outgoing response', {
|
|
38
|
+
requestId,
|
|
39
|
+
method: req.method,
|
|
40
|
+
path: req.path,
|
|
41
|
+
statusCode: res.statusCode,
|
|
42
|
+
duration: `${duration}ms`,
|
|
43
|
+
});
|
|
44
|
+
return originalSend.call(this, data);
|
|
45
|
+
};
|
|
46
|
+
next();
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Filter sensitive headers
|
|
51
|
+
*/
|
|
52
|
+
function filterSensitiveHeaders(headers) {
|
|
53
|
+
const filtered = {};
|
|
54
|
+
const sensitiveHeaders = middleware_config_1.MIDDLEWARE_CONFIG.logging.sensitiveHeaders;
|
|
55
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
56
|
+
if (sensitiveHeaders.includes(key.toLowerCase())) {
|
|
57
|
+
filtered[key] = '[REDACTED]';
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
filtered[key] = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return filtered;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Filter sensitive data from request body
|
|
67
|
+
*/
|
|
68
|
+
function filterSensitiveData(body) {
|
|
69
|
+
if (typeof body !== 'object' || body === null) {
|
|
70
|
+
return body;
|
|
71
|
+
}
|
|
72
|
+
const filtered = Array.isArray(body) ? [] : {};
|
|
73
|
+
const sensitiveFields = ['password', 'token', 'secret', 'apiKey', 'creditCard'];
|
|
74
|
+
for (const [key, value] of Object.entries(body)) {
|
|
75
|
+
if (sensitiveFields.some((field) => key.toLowerCase().includes(field.toLowerCase()))) {
|
|
76
|
+
filtered[key] = '[REDACTED]';
|
|
77
|
+
}
|
|
78
|
+
else if (typeof value === 'object' && value !== null) {
|
|
79
|
+
filtered[key] = filterSensitiveData(value);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
filtered[key] = value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return filtered;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=logging.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.middleware.js","sourceRoot":"","sources":["../../../../src/middleware/logging.middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limiting Middleware
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: express-rate-limit uses an in-memory store by default.
|
|
5
|
+
* In serverless environments (Cloud Functions), each instance has its own
|
|
6
|
+
* memory and rate limits reset on cold starts. This means rate limiting
|
|
7
|
+
* is per-instance and won't protect against distributed abuse at scale.
|
|
8
|
+
*
|
|
9
|
+
* For production hardening, replace the default store with a shared store:
|
|
10
|
+
* - Redis: use rate-limit-redis with the existing redis-cache-provider
|
|
11
|
+
* - Firestore: implement a custom store using firestore-connector
|
|
12
|
+
* - Firebase App Check: for client-side abuse prevention
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Create standard rate limiter
|
|
16
|
+
*/
|
|
17
|
+
export declare function createRateLimiter(): import("express-rate-limit").RateLimitRequestHandler;
|
|
18
|
+
/**
|
|
19
|
+
* Create strict rate limiter for sensitive endpoints
|
|
20
|
+
*/
|
|
21
|
+
export declare function createStrictRateLimiter(): import("express-rate-limit").RateLimitRequestHandler;
|
|
22
|
+
/**
|
|
23
|
+
* Create per-user rate limiter
|
|
24
|
+
*/
|
|
25
|
+
export declare function createPerUserRateLimiter(max?: number, windowMs?: number): import("express-rate-limit").RateLimitRequestHandler;
|
|
26
|
+
//# sourceMappingURL=rateLimit.middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.middleware.d.ts","sourceRoot":"","sources":["../../../../src/middleware/rateLimit.middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH;;GAEG;AACH,wBAAgB,iBAAiB,yDAuBhC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,yDAqBtC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,SAAM,EAAE,QAAQ,SAAiB,wDA0B5E"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rate Limiting Middleware
|
|
4
|
+
*
|
|
5
|
+
* IMPORTANT: express-rate-limit uses an in-memory store by default.
|
|
6
|
+
* In serverless environments (Cloud Functions), each instance has its own
|
|
7
|
+
* memory and rate limits reset on cold starts. This means rate limiting
|
|
8
|
+
* is per-instance and won't protect against distributed abuse at scale.
|
|
9
|
+
*
|
|
10
|
+
* For production hardening, replace the default store with a shared store:
|
|
11
|
+
* - Redis: use rate-limit-redis with the existing redis-cache-provider
|
|
12
|
+
* - Firestore: implement a custom store using firestore-connector
|
|
13
|
+
* - Firebase App Check: for client-side abuse prevention
|
|
14
|
+
*/
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.createRateLimiter = createRateLimiter;
|
|
20
|
+
exports.createStrictRateLimiter = createStrictRateLimiter;
|
|
21
|
+
exports.createPerUserRateLimiter = createPerUserRateLimiter;
|
|
22
|
+
const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
|
|
23
|
+
const middleware_config_1 = require("../config/middleware.config");
|
|
24
|
+
const utils_logger_1 = require("@xbg/utils-logger");
|
|
25
|
+
/**
|
|
26
|
+
* Create standard rate limiter
|
|
27
|
+
*/
|
|
28
|
+
function createRateLimiter() {
|
|
29
|
+
return (0, express_rate_limit_1.default)({
|
|
30
|
+
windowMs: middleware_config_1.MIDDLEWARE_CONFIG.rateLimit.windowMs,
|
|
31
|
+
max: middleware_config_1.MIDDLEWARE_CONFIG.rateLimit.max,
|
|
32
|
+
standardHeaders: true,
|
|
33
|
+
legacyHeaders: false,
|
|
34
|
+
skipSuccessfulRequests: middleware_config_1.MIDDLEWARE_CONFIG.rateLimit.skipSuccessfulRequests,
|
|
35
|
+
skipFailedRequests: middleware_config_1.MIDDLEWARE_CONFIG.rateLimit.skipFailedRequests,
|
|
36
|
+
handler: (req, res) => {
|
|
37
|
+
utils_logger_1.logger.warn('Rate limit exceeded', {
|
|
38
|
+
ip: req.ip,
|
|
39
|
+
path: req.path,
|
|
40
|
+
});
|
|
41
|
+
res.status(429).json({
|
|
42
|
+
success: false,
|
|
43
|
+
error: {
|
|
44
|
+
code: 'RATE_LIMIT_EXCEEDED',
|
|
45
|
+
message: 'Too many requests, please try again later',
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create strict rate limiter for sensitive endpoints
|
|
53
|
+
*/
|
|
54
|
+
function createStrictRateLimiter() {
|
|
55
|
+
return (0, express_rate_limit_1.default)({
|
|
56
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
57
|
+
max: 5, // 5 requests per window
|
|
58
|
+
standardHeaders: true,
|
|
59
|
+
legacyHeaders: false,
|
|
60
|
+
handler: (req, res) => {
|
|
61
|
+
utils_logger_1.logger.warn('Strict rate limit exceeded', {
|
|
62
|
+
ip: req.ip,
|
|
63
|
+
path: req.path,
|
|
64
|
+
});
|
|
65
|
+
res.status(429).json({
|
|
66
|
+
success: false,
|
|
67
|
+
error: {
|
|
68
|
+
code: 'RATE_LIMIT_EXCEEDED',
|
|
69
|
+
message: 'Too many attempts, please try again later',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create per-user rate limiter
|
|
77
|
+
*/
|
|
78
|
+
function createPerUserRateLimiter(max = 100, windowMs = 15 * 60 * 1000) {
|
|
79
|
+
return (0, express_rate_limit_1.default)({
|
|
80
|
+
windowMs,
|
|
81
|
+
max,
|
|
82
|
+
standardHeaders: true,
|
|
83
|
+
legacyHeaders: false,
|
|
84
|
+
keyGenerator: (req) => {
|
|
85
|
+
const user = req.user;
|
|
86
|
+
return (user === null || user === void 0 ? void 0 : user.uid) || req.ip || 'anonymous';
|
|
87
|
+
},
|
|
88
|
+
handler: (req, res) => {
|
|
89
|
+
var _a;
|
|
90
|
+
utils_logger_1.logger.warn('Per-user rate limit exceeded', {
|
|
91
|
+
userId: (_a = req.user) === null || _a === void 0 ? void 0 : _a.uid,
|
|
92
|
+
ip: req.ip,
|
|
93
|
+
path: req.path,
|
|
94
|
+
});
|
|
95
|
+
res.status(429).json({
|
|
96
|
+
success: false,
|
|
97
|
+
error: {
|
|
98
|
+
code: 'RATE_LIMIT_EXCEEDED',
|
|
99
|
+
message: 'Too many requests, please try again later',
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=rateLimit.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.middleware.js","sourceRoot":"","sources":["../../../../src/middleware/rateLimit.middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request ID Middleware
|
|
3
|
+
* Adds unique request ID to each request for tracing
|
|
4
|
+
*/
|
|
5
|
+
import { Request, Response, NextFunction } from 'express';
|
|
6
|
+
/**
|
|
7
|
+
* Request ID middleware
|
|
8
|
+
* Generates or uses existing request ID for correlation tracking
|
|
9
|
+
*/
|
|
10
|
+
export declare function requestIdMiddleware(): (req: Request, res: Response, next: NextFunction) => void;
|
|
11
|
+
//# sourceMappingURL=requestId.middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestId.middleware.d.ts","sourceRoot":"","sources":["../../../../src/middleware/requestId.middleware.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAI1D;;;GAGG;AACH,wBAAgB,mBAAmB,KACzB,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UAcxD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Request ID Middleware
|
|
4
|
+
* Adds unique request ID to each request for tracing
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.requestIdMiddleware = requestIdMiddleware;
|
|
8
|
+
const uuid_1 = require("uuid");
|
|
9
|
+
const middleware_config_1 = require("../config/middleware.config");
|
|
10
|
+
/**
|
|
11
|
+
* Request ID middleware
|
|
12
|
+
* Generates or uses existing request ID for correlation tracking
|
|
13
|
+
*/
|
|
14
|
+
function requestIdMiddleware() {
|
|
15
|
+
return (req, res, next) => {
|
|
16
|
+
const headerName = middleware_config_1.MIDDLEWARE_CONFIG.requestId.headerName;
|
|
17
|
+
// Get existing request ID or generate new one
|
|
18
|
+
const requestId = req.headers[headerName.toLowerCase()] || (0, uuid_1.v4)();
|
|
19
|
+
// Set request ID on request object
|
|
20
|
+
req.headers[headerName.toLowerCase()] = requestId;
|
|
21
|
+
// Set request ID in response header
|
|
22
|
+
res.setHeader(headerName, requestId);
|
|
23
|
+
next();
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=requestId.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestId.middleware.js","sourceRoot":"","sources":["../../../../src/middleware/requestId.middleware.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAUH,kDAeC;AAtBD,+BAAoC;AACpC,mEAAgE;AAEhE;;;GAGG;AACH,SAAgB,mBAAmB;IACjC,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACzD,MAAM,UAAU,GAAG,qCAAiB,CAAC,SAAS,CAAC,UAAU,CAAC;QAE1D,8CAA8C;QAC9C,MAAM,SAAS,GAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAY,IAAI,IAAA,SAAM,GAAE,CAAC;QAEhF,mCAAmC;QACnC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,GAAG,SAAS,CAAC;QAElD,oCAAoC;QACpC,GAAG,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAErC,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Middleware
|
|
3
|
+
* Input validation and sanitization
|
|
4
|
+
*/
|
|
5
|
+
import { Request, Response, NextFunction } from 'express';
|
|
6
|
+
import { ValidationChain } from 'express-validator';
|
|
7
|
+
/**
|
|
8
|
+
* Validation middleware factory
|
|
9
|
+
* Runs express-validator chains and returns errors
|
|
10
|
+
*/
|
|
11
|
+
export declare function validate(validations: ValidationChain[]): (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
|
|
12
|
+
/**
|
|
13
|
+
* Sanitize request body
|
|
14
|
+
* Remove potentially dangerous characters
|
|
15
|
+
*/
|
|
16
|
+
export declare function sanitizeBody(): (req: Request, _res: Response, next: NextFunction) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Validate pagination parameters
|
|
19
|
+
*/
|
|
20
|
+
export declare function validatePagination(): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
|
|
21
|
+
/**
|
|
22
|
+
* Validate UUID parameter
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateUUID(paramName?: string): (req: Request, res: Response, next: NextFunction) => void | Response<any, Record<string, any>>;
|
|
25
|
+
//# sourceMappingURL=validation.middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.middleware.d.ts","sourceRoot":"","sources":["../../../../src/middleware/validation.middleware.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAoB,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGtE;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,WAAW,EAAE,eAAe,EAAE,IACvC,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,wDA4B9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,KAClB,KAAK,OAAO,EAAE,MAAM,QAAQ,EAAE,MAAM,YAAY,UAMzD;AAmCD;;GAEG;AACH,wBAAgB,kBAAkB,KACxB,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,+CA6BxD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,SAAO,IAGnC,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,+CAexD"}
|