mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-21 09:03:02 +00:00
committed by
Rainer Killinger
parent
f11376ecf8
commit
12b71ba1f1
77
src/app.ts
77
src/app.ts
@@ -13,9 +13,13 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import {SCNotFoundErrorResponse, SCUnsupportedMediaTypeErrorResponse} from '@openstapps/core';
|
||||
import {
|
||||
SCInternalServerErrorResponse,
|
||||
SCNotFoundErrorResponse,
|
||||
SCSyntaxErrorResponse,
|
||||
SCUnsupportedMediaTypeErrorResponse,
|
||||
} from '@openstapps/core';
|
||||
import {Validator} from '@openstapps/core-tools/lib/validate';
|
||||
import * as bodyParser from 'body-parser';
|
||||
import * as config from 'config';
|
||||
import * as cors from 'cors';
|
||||
import * as express from 'express';
|
||||
@@ -35,26 +39,61 @@ import {DatabaseConstructor} from './storage/Database';
|
||||
import {Elasticsearch} from './storage/elasticsearch/Elasticsearch';
|
||||
|
||||
export const app = express();
|
||||
const isTestEnvironment = process.env.NODE_ENV !== 'production';
|
||||
|
||||
async function configureApp() {
|
||||
// only accept json as content type for all requests
|
||||
app.use(bodyParser.json({
|
||||
limit: '500kb',
|
||||
type: (req) => {
|
||||
const contentType = typeof req.headers['Content-Type'] === 'string' ?
|
||||
req.headers['Content-Type'] : req.headers['content-type'];
|
||||
if (typeof contentType === 'string' && contentType.match(/^application\/json/)) {
|
||||
return true;
|
||||
} else {
|
||||
throw new SCUnsupportedMediaTypeErrorResponse(process.env.NODE_ENV !== 'production');
|
||||
}
|
||||
},
|
||||
})); // 500kb should be reasonably large
|
||||
|
||||
// use morgan as a request logger
|
||||
// request loggers have to be the first middleware to be set in express
|
||||
app.use(morgan('dev'));
|
||||
|
||||
// only accept json as content type for all requests
|
||||
app.use((req, res, next) => {
|
||||
// Get the content type
|
||||
let contentType = '';
|
||||
if (typeof req.headers['Content-Type'] === 'string') {
|
||||
contentType = req.headers['Content-Type'] as string;
|
||||
} else if (typeof req.headers['content-type'] === 'string') {
|
||||
contentType = req.headers['content-type'];
|
||||
}
|
||||
|
||||
// Only accept json as content type
|
||||
if (contentType === '' || contentType.match(/^application\/json$/) === null) {
|
||||
const err = new SCUnsupportedMediaTypeErrorResponse(isTestEnvironment);
|
||||
res.status(err.statusCode);
|
||||
res.json(err);
|
||||
return;
|
||||
}
|
||||
|
||||
const bodyBuffer: any[] = [];
|
||||
let bodySize = 0;
|
||||
const chunkGatherer = (chunk: Buffer) => {
|
||||
bodySize += chunk.byteLength;
|
||||
if (bodySize > 512 * 1024) {
|
||||
req.off('data', chunkGatherer);
|
||||
req.off('end', endCallback);
|
||||
const err = new SCInternalServerErrorResponse(new Error('Request body is too large!'), isTestEnvironment);
|
||||
res.status(err.statusCode);
|
||||
res.json(err);
|
||||
return;
|
||||
}
|
||||
bodyBuffer.push(chunk);
|
||||
};
|
||||
|
||||
const endCallback = () => {
|
||||
req.body = Buffer.concat(bodyBuffer).toString();
|
||||
|
||||
try {
|
||||
req.body = JSON.parse(req.body);
|
||||
next();
|
||||
} catch (catchErr) {
|
||||
const err = new SCSyntaxErrorResponse(catchErr.message, isTestEnvironment);
|
||||
res.status(err.statusCode);
|
||||
res.json(err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
req.on('data', chunkGatherer).on('end', endCallback);
|
||||
});
|
||||
|
||||
const databases: {[name: string]: DatabaseConstructor} = {
|
||||
elasticsearch: Elasticsearch,
|
||||
};
|
||||
@@ -137,7 +176,7 @@ async function configureApp() {
|
||||
// allow cors preflight requests on every route
|
||||
app.options('*', cors(corsOptions));
|
||||
|
||||
app.set('isProductiveEnvironment', process.env.NODE_ENV !== 'production');
|
||||
app.set('isTestEnvironment', isTestEnvironment);
|
||||
|
||||
// load routes before plugins
|
||||
// they now can be used or overwritten by any plugin
|
||||
@@ -153,7 +192,7 @@ async function configureApp() {
|
||||
|
||||
// add a route for a missing resource (404)
|
||||
app.use((_req, res) => {
|
||||
const errorResponse = new SCNotFoundErrorResponse(process.env.NODE_ENV !== 'production');
|
||||
const errorResponse = new SCNotFoundErrorResponse(isTestEnvironment);
|
||||
res.status(errorResponse.statusCode);
|
||||
res.json(errorResponse);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user