-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
102 lines (91 loc) · 2.96 KB
/
Copy pathindex.ts
File metadata and controls
102 lines (91 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import cluster from 'cluster';
import cors from 'cors';
import helmet from 'helmet';
import os from 'os';
import { ApiError, InternalError, Logger, NotFoundError } from './config';
import './register-aliases';
import setupSwagger from './utils/swagger';
const logger = new Logger();
const numberOfCores = os.cpus().length;
import express, { NextFunction, Request, Response } from 'express';
import { config } from './config';
const app = express();
// Limit requests from same API
if (cluster.isPrimary && numberOfCores > 1) {
for (let i = 0; i < numberOfCores; i++) {
// fork child process
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
// console.log(`worker ${worker.process.pid} died`);
// console.log("Let's fork another worker!");
cluster.fork();
});
// console.log(`Master PID: ${process.pid}`);
} else {
////////////////////////////////////////////
////// SECURITY CONFIG
////////////////////////////
// Apply standard HTTP security headers with Helmet
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
},
},
permittedCrossDomainPolicies: {
permittedPolicies: "none", // oder "master-only", etc.
},
}),
);
// CORS with dynamic whitelist and credential support
app.use(cors({
origin: (origin, callback) => {
if (!origin || config.corsWhitelist.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
optionsSuccessStatus: 200,
methods: 'POST, GET',
credentials: true,
}));
// Use built-in express middleware for body parsing
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Swagger
setupSwagger(app, Number(config.port));
// Load routes
const healthRoutes = require('./routes/health.routes');
const userRoutes = require('./routes/user.routes');
app.use('/api/health', healthRoutes);
app.use('/api/users', config.authLimiter, userRoutes);
// Error handling
app.all('*', (req: Request, res: Response, next: NextFunction) => {
next(new NotFoundError(`Route ${req.originalUrl} not found!`));
});
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
if (err instanceof ApiError) {
logger.error(err.message + ', ' + err.stack + ', ' + err.type);
ApiError.handle(err, res);
} else {
if (config.environment === 'development') {
logger.error(err);
return res.status(500).send(err.message);
}
logger.error(err);
ApiError.handle(new InternalError('Something went wrong!'), res);
// ApiError.handle(new InternalError(), res);
}
});
if (cluster.worker?.id === 1) {
app.listen(config.port, () => {
console.log(`Server with ${numberOfCores} cores listening on port ${config.port}`);
console.log(`Open: http://localhost:${config.port}`);
});
} else {
app.listen(config.port, () => {});
}
}