@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.
@@ -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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"}