@goatlab/node-backend 0.2.4 → 0.2.6
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/dist/container/Container.d.ts +28 -24
- package/dist/container/Container.js +135 -162
- package/dist/container/Container.js.map +1 -1
- package/dist/container/helpers.d.ts +8 -0
- package/dist/container/helpers.js +22 -0
- package/dist/container/helpers.js.map +1 -1
- package/dist/container/types.d.ts +10 -0
- package/dist/server/bootstraps/getExpressTrpcApp.d.ts +5 -1
- package/dist/server/bootstraps/getExpressTrpcApp.js +160 -18
- package/dist/server/bootstraps/getExpressTrpcApp.js.map +1 -1
- package/dist/server/middleware/productionError.middleware.d.ts +16 -0
- package/dist/server/middleware/productionError.middleware.js +94 -0
- package/dist/server/middleware/productionError.middleware.js.map +1 -0
- package/dist/server/middleware/security.middleware.d.ts +28 -0
- package/dist/server/middleware/security.middleware.js +151 -0
- package/dist/server/middleware/security.middleware.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +13 -1
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCorsOptions = getCorsOptions;
|
|
4
|
+
exports.getHelmetOptions = getHelmetOptions;
|
|
5
|
+
exports.createRateLimiter = createRateLimiter;
|
|
6
|
+
exports.createAuthRateLimiter = createAuthRateLimiter;
|
|
7
|
+
exports.createApiRateLimiter = createApiRateLimiter;
|
|
8
|
+
exports.additionalSecurityHeaders = additionalSecurityHeaders;
|
|
9
|
+
const express_rate_limit_1 = require("express-rate-limit");
|
|
10
|
+
/**
|
|
11
|
+
* Get CORS configuration based on environment
|
|
12
|
+
*/
|
|
13
|
+
function getCorsOptions() {
|
|
14
|
+
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',').map(origin => origin.trim()) || [];
|
|
15
|
+
// In development, allow localhost origins
|
|
16
|
+
if (process.env.NODE_ENV !== 'prod' && allowedOrigins.length === 0) {
|
|
17
|
+
allowedOrigins.push('http://localhost:3000', 'http://localhost:3001', 'http://localhost:5173');
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
origin: (origin, callback) => {
|
|
21
|
+
// Allow requests with no origin (like mobile apps or Postman)
|
|
22
|
+
if (!origin && process.env.NODE_ENV !== 'prod') {
|
|
23
|
+
return callback(null, true);
|
|
24
|
+
}
|
|
25
|
+
if (!origin || allowedOrigins.includes(origin)) {
|
|
26
|
+
callback(null, true);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
callback(new Error('Not allowed by CORS'));
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
credentials: true,
|
|
33
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
|
|
34
|
+
allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-ID'],
|
|
35
|
+
exposedHeaders: [
|
|
36
|
+
'X-Request-ID',
|
|
37
|
+
'X-RateLimit-Limit',
|
|
38
|
+
'X-RateLimit-Remaining',
|
|
39
|
+
'X-RateLimit-Reset'
|
|
40
|
+
],
|
|
41
|
+
maxAge: 86400, // 24 hours
|
|
42
|
+
optionsSuccessStatus: 200 // Some legacy browsers choke on 204
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get Helmet configuration for enhanced security headers
|
|
47
|
+
*/
|
|
48
|
+
function getHelmetOptions() {
|
|
49
|
+
const isDevelopment = process.env.NODE_ENV !== 'prod';
|
|
50
|
+
return {
|
|
51
|
+
contentSecurityPolicy: isDevelopment
|
|
52
|
+
? false
|
|
53
|
+
: {
|
|
54
|
+
directives: {
|
|
55
|
+
defaultSrc: ["'self'"],
|
|
56
|
+
scriptSrc: ["'self'", "'unsafe-inline'"], // Consider removing unsafe-inline in production
|
|
57
|
+
styleSrc: ["'self'", "'unsafe-inline'"],
|
|
58
|
+
imgSrc: ["'self'", 'data:', 'https:'],
|
|
59
|
+
connectSrc: ["'self'"],
|
|
60
|
+
fontSrc: ["'self'"],
|
|
61
|
+
objectSrc: ["'none'"],
|
|
62
|
+
mediaSrc: ["'self'"],
|
|
63
|
+
frameSrc: ["'none'"],
|
|
64
|
+
baseUri: ["'self'"],
|
|
65
|
+
formAction: ["'self'"],
|
|
66
|
+
frameAncestors: ["'none'"],
|
|
67
|
+
upgradeInsecureRequests: []
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
hsts: {
|
|
71
|
+
maxAge: 31536000, // 1 year
|
|
72
|
+
includeSubDomains: true,
|
|
73
|
+
preload: true
|
|
74
|
+
},
|
|
75
|
+
noSniff: true,
|
|
76
|
+
xssFilter: true,
|
|
77
|
+
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
|
|
78
|
+
permittedCrossDomainPolicies: false,
|
|
79
|
+
hidePoweredBy: true,
|
|
80
|
+
ieNoOpen: true,
|
|
81
|
+
frameguard: { action: 'deny' }
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create rate limiter with default configuration
|
|
86
|
+
*/
|
|
87
|
+
function createRateLimiter(options) {
|
|
88
|
+
return (0, express_rate_limit_1.default)({
|
|
89
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
90
|
+
max: 100, // Limit each IP to 100 requests per windowMs
|
|
91
|
+
message: 'Too many requests from this IP, please try again later.',
|
|
92
|
+
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
|
|
93
|
+
legacyHeaders: false, // Disable the `X-RateLimit-*` headers
|
|
94
|
+
skipSuccessfulRequests: false,
|
|
95
|
+
// Skip rate limiting validation errors in test environment
|
|
96
|
+
validate: process.env.NODE_ENV === 'test' ? false : undefined,
|
|
97
|
+
handler: (_req, res) => {
|
|
98
|
+
res.status(429).json({
|
|
99
|
+
error: {
|
|
100
|
+
code: 'RATE_LIMIT_EXCEEDED',
|
|
101
|
+
message: 'Too many requests, please try again later.',
|
|
102
|
+
retryAfter: res.getHeader('Retry-After')
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
...options
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Create stricter rate limiter for authentication endpoints
|
|
111
|
+
*/
|
|
112
|
+
function createAuthRateLimiter() {
|
|
113
|
+
return createRateLimiter({
|
|
114
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
115
|
+
max: 5, // Limit each IP to 5 requests per windowMs
|
|
116
|
+
skipSuccessfulRequests: true, // Don't count successful requests
|
|
117
|
+
message: 'Too many authentication attempts, please try again later.'
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create rate limiter for API endpoints
|
|
122
|
+
*/
|
|
123
|
+
function createApiRateLimiter() {
|
|
124
|
+
const maxRequests = process.env.API_RATE_LIMIT
|
|
125
|
+
? parseInt(process.env.API_RATE_LIMIT, 10)
|
|
126
|
+
: 100;
|
|
127
|
+
return createRateLimiter({
|
|
128
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
129
|
+
max: maxRequests,
|
|
130
|
+
message: 'API rate limit exceeded, please try again later.'
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Additional security headers not covered by Helmet
|
|
135
|
+
*/
|
|
136
|
+
function additionalSecurityHeaders() {
|
|
137
|
+
return (req, res, next) => {
|
|
138
|
+
// Permissions Policy (formerly Feature Policy)
|
|
139
|
+
res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), accelerometer=()');
|
|
140
|
+
// Additional security headers
|
|
141
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
142
|
+
res.setHeader('X-Frame-Options', 'DENY');
|
|
143
|
+
res.setHeader('X-XSS-Protection', '1; mode=block');
|
|
144
|
+
// Clear site data on logout (if logout endpoint)
|
|
145
|
+
if (req.path === '/logout' || req.path === '/api/logout') {
|
|
146
|
+
res.setHeader('Clear-Site-Data', '"cache", "cookies", "storage"');
|
|
147
|
+
}
|
|
148
|
+
next();
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=security.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.middleware.js","sourceRoot":"","sources":["../../../src/server/middleware/security.middleware.ts"],"names":[],"mappings":"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"}
|