banana
/
definma-api
Archived
2
Fork 0
This repository has been archived on 2023-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
definma-api/src/index.ts

145 lines
3.9 KiB
TypeScript
Raw Permalink Normal View History

2020-01-14 13:25:13 +01:00
import express from 'express';
import bodyParser from 'body-parser';
2020-06-05 10:51:03 +02:00
import compression from 'compression';
2020-04-23 13:59:45 +02:00
import contentFilter from 'content-filter';
2020-06-05 10:51:03 +02:00
import helmet from 'helmet';
2020-07-09 13:48:27 +02:00
import cors from 'cors';
2020-05-12 14:05:47 +02:00
import api from './api';
import db from './db';
2020-08-07 08:37:25 +02:00
import Mail from './helpers/mail';
2020-01-14 13:25:13 +01:00
// Tell if server is running in debug or production environment
2020-08-04 13:54:14 +02:00
console.info(process.env.NODE_ENV === 'production' ?
'===== PRODUCTION =====' : process.env.NODE_ENV === 'test' ? '' :'===== DEVELOPMENT =====');
2020-01-14 13:25:13 +01:00
// Mongodb connection
db.connect();
2020-04-20 16:17:43 +02:00
// Mail service
2020-08-07 08:37:25 +02:00
Mail.init();
// Create Express app
2020-01-14 13:25:13 +01:00
const app = express();
// Get port from environment, defaults to 3000
2020-01-14 13:25:13 +01:00
const port = process.env.PORT || 3000;
// Security headers
2020-07-28 13:59:13 +02:00
const defaultHeaderConfig = {
contentSecurityPolicy: {
directives: {
defaultSrc: [`'none'`],
baseUri: [`'self'`],
formAction: [`'none'`],
frameAncestors: [`'none'`]
}
2020-07-28 13:59:13 +02:00
},
frameguard: {
action: 'deny'
},
permittedCrossDomainPolicies: true,
refererPolicy: true
};
app.use(helmet(defaultHeaderConfig));
// Special CSP header for api-doc
app.use('/api-doc', helmet.contentSecurityPolicy({
2020-07-28 13:59:13 +02:00
...defaultHeaderConfig,
directives: {
2020-07-30 11:36:03 +02:00
defaultSrc: [`'none'`],
scriptSrc: [`'self'`],
connectSrc: [`'self'`],
styleSrc: [`'self'`, `'unsafe-inline'`],
2020-07-28 13:59:13 +02:00
imgSrc: [`'self'`, 'data:']
}
}));
// Special CSP header for the intro-presentation
2020-08-09 17:25:32 +02:00
app.use(/\/static\/intro-presentation\/(index.html)?/, helmet.contentSecurityPolicy({
2020-08-07 15:21:16 +02:00
...defaultHeaderConfig,
directives: {
defaultSrc: [`'none'`],
scriptSrc: [`'self'`, `'unsafe-inline'`],
styleSrc: [`'self'`, `'unsafe-inline'`],
imgSrc: [`'self'`]
}
}));
// Special CSP header for the bosch-logo.svg
2020-08-07 15:21:16 +02:00
app.use('/static/*.svg', helmet.contentSecurityPolicy({
2020-07-28 13:59:13 +02:00
...defaultHeaderConfig,
directives: {
styleSrc: [`'unsafe-inline'`]
}
}));
// Middleware
app.use(compression()); // Compress responses
app.use(express.json({ limit: '5mb'}));
app.use(express.urlencoded({ extended: false, limit: '5mb' }));
app.use(bodyParser.json());
2020-08-04 13:54:14 +02:00
app.use(contentFilter({
urlBlackList: ['$', '&&', '||'],
bodyBlackList: ['$', '{', '&&', '||'],
appendFound: true
})); // Filter URL query attacks
app.use((err, req, res, ignore) => { // BodyParser error handling
res.status(400).send({status: 'Invalid JSON body'});
});
app.use((req, res, next) => { // No database connection error
2020-04-23 13:59:45 +02:00
if (db.getState().db) {
next();
}
else {
2020-07-09 13:48:27 +02:00
console.error('No database connection');
2020-04-23 13:59:45 +02:00
res.status(500).send({status: 'Internal server error'});
}
});
2020-07-09 13:48:27 +02:00
app.use(cors()); // CORS headers
app.use(require('./helpers/authorize')); // Handle authentication
// Redirect /api routes for Angular proxy in development
if (process.env.NODE_ENV !== 'production') {
2020-06-29 15:50:24 +02:00
app.use('/api/:url([^]+)', (req, res) => {
if (/help\//.test(req.params.url)) { // Encode URI again for help route
2020-09-03 16:26:16 +02:00
req.params.url = 'help/' + encodeURIComponent(req.params.url.replace('help/', ''));
}
req.url = '/' + req.params.url;
2020-06-29 15:50:24 +02:00
app.handle(req, res);
});
}
// Require routes
2021-02-24 13:59:25 +01:00
app.use('/', require('./routes/help'));
app.use('/', require('./routes/material'));
2020-08-13 12:07:40 +02:00
app.use('/', require('./routes/measurement'));
app.use('/', require('./routes/model'));
2021-02-24 13:59:25 +01:00
app.use('/', require('./routes/prediction'));
app.use('/', require('./routes/root'));
app.use('/', require('./routes/sample'));
app.use('/', require('./routes/template'));
app.use('/', require('./routes/user'));
2020-01-14 13:25:13 +01:00
// Static files
2020-04-29 15:07:07 +02:00
app.use('/static', express.static('static'));
2020-01-14 13:25:13 +01:00
// Swagger UI
app.use('/api-doc', api());
2020-01-14 13:25:13 +01:00
app.use((req, res) => { // 404 error handling
res.status(404).json({status: 'Not found'});
});
app.use((err, req, res, ignore) => { // Internal server error handling
console.error(err);
res.status(500).json({status: 'Internal server error'});
});
// Hook up server to port
const server = app.listen(port, () => {
2020-05-07 21:55:29 +02:00
console.info(process.env.NODE_ENV === 'test' ? '' : `Listening on http://localhost:${port}`);
2020-01-14 13:25:13 +01:00
});
2021-02-24 13:59:25 +01:00
module.exports = server;