mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-22 09:32:41 +00:00
committed by
Rainer Killinger
parent
f11376ecf8
commit
12b71ba1f1
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1257,7 +1257,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-styles": "^2.2.1",
|
"ansi-styles": "^2.2.1",
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
"@openstapps/core": "0.11.0",
|
"@openstapps/core": "0.11.0",
|
||||||
"@openstapps/core-tools": "0.3.0",
|
"@openstapps/core-tools": "0.3.0",
|
||||||
"@openstapps/logger": "0.0.5",
|
"@openstapps/logger": "0.0.5",
|
||||||
"body-parser": "1.18.3",
|
|
||||||
"config": "3.0.1",
|
"config": "3.0.1",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"elasticsearch": "15.4.1",
|
"elasticsearch": "15.4.1",
|
||||||
@@ -44,7 +43,6 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@openstapps/configuration": "0.6.0",
|
"@openstapps/configuration": "0.6.0",
|
||||||
"@types/body-parser": "1.17.0",
|
|
||||||
"@types/config": "0.0.34",
|
"@types/config": "0.0.34",
|
||||||
"@types/cors": "2.8.4",
|
"@types/cors": "2.8.4",
|
||||||
"@types/elasticsearch": "5.0.31",
|
"@types/elasticsearch": "5.0.31",
|
||||||
|
|||||||
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
|
* 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/>.
|
* 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 {Validator} from '@openstapps/core-tools/lib/validate';
|
||||||
import * as bodyParser from 'body-parser';
|
|
||||||
import * as config from 'config';
|
import * as config from 'config';
|
||||||
import * as cors from 'cors';
|
import * as cors from 'cors';
|
||||||
import * as express from 'express';
|
import * as express from 'express';
|
||||||
@@ -35,26 +39,61 @@ import {DatabaseConstructor} from './storage/Database';
|
|||||||
import {Elasticsearch} from './storage/elasticsearch/Elasticsearch';
|
import {Elasticsearch} from './storage/elasticsearch/Elasticsearch';
|
||||||
|
|
||||||
export const app = express();
|
export const app = express();
|
||||||
|
const isTestEnvironment = process.env.NODE_ENV !== 'production';
|
||||||
|
|
||||||
async function configureApp() {
|
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
|
// request loggers have to be the first middleware to be set in express
|
||||||
app.use(morgan('dev'));
|
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} = {
|
const databases: {[name: string]: DatabaseConstructor} = {
|
||||||
elasticsearch: Elasticsearch,
|
elasticsearch: Elasticsearch,
|
||||||
};
|
};
|
||||||
@@ -137,7 +176,7 @@ async function configureApp() {
|
|||||||
// allow cors preflight requests on every route
|
// allow cors preflight requests on every route
|
||||||
app.options('*', cors(corsOptions));
|
app.options('*', cors(corsOptions));
|
||||||
|
|
||||||
app.set('isProductiveEnvironment', process.env.NODE_ENV !== 'production');
|
app.set('isTestEnvironment', isTestEnvironment);
|
||||||
|
|
||||||
// load routes before plugins
|
// load routes before plugins
|
||||||
// they now can be used or overwritten by any plugin
|
// 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)
|
// add a route for a missing resource (404)
|
||||||
app.use((_req, res) => {
|
app.use((_req, res) => {
|
||||||
const errorResponse = new SCNotFoundErrorResponse(process.env.NODE_ENV !== 'production');
|
const errorResponse = new SCNotFoundErrorResponse(isTestEnvironment);
|
||||||
res.status(errorResponse.statusCode);
|
res.status(errorResponse.statusCode);
|
||||||
res.json(errorResponse);
|
res.json(errorResponse);
|
||||||
});
|
});
|
||||||
|
|||||||
12
src/cli.ts
12
src/cli.ts
@@ -86,8 +86,12 @@ function onError(error: Error | any) {
|
|||||||
*/
|
*/
|
||||||
function onListening() {
|
function onListening() {
|
||||||
const addr = server.address();
|
const addr = server.address();
|
||||||
const bind = typeof addr === 'string'
|
if (addr === null) {
|
||||||
? 'pipe ' + addr
|
logger.warn('Listening on null');
|
||||||
: 'port ' + addr.port;
|
} else {
|
||||||
logger.ok('Listening on ' + bind);
|
const bind = typeof addr === 'string'
|
||||||
|
? 'pipe ' + addr
|
||||||
|
: 'port ' + addr.port;
|
||||||
|
logger.ok('Listening on ' + bind);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const bulkAddRouter = createRoute<SCBulkAddResponse>(
|
|||||||
|
|
||||||
if (typeof bulk === 'undefined') {
|
if (typeof bulk === 'undefined') {
|
||||||
logger.warn(`Bulk with ${params.UID} not found.`);
|
logger.warn(`Bulk with ${params.UID} not found.`);
|
||||||
throw new SCNotFoundErrorResponse(app.get('isProductiveEnvironment'));
|
throw new SCNotFoundErrorResponse(app.get('isTestEnvironment'));
|
||||||
}
|
}
|
||||||
|
|
||||||
await bulkMemory.database.post(request, bulk);
|
await bulkMemory.database.post(request, bulk);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export const bulkDoneRouter = createRoute<SCBulkDoneResponse>(
|
|||||||
|
|
||||||
if (typeof bulk === 'undefined') {
|
if (typeof bulk === 'undefined') {
|
||||||
logger.warn(`Bulk with ${params.UID} not found.`);
|
logger.warn(`Bulk with ${params.UID} not found.`);
|
||||||
throw new SCNotFoundErrorResponse(app.get('isProductiveEnvironment'));
|
throw new SCNotFoundErrorResponse(app.get('isTestEnvironment'));
|
||||||
}
|
}
|
||||||
|
|
||||||
bulk.state = 'done';
|
bulk.state = 'done';
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export function createRoute<RETURNTYPE>(
|
|||||||
if (requestValidation.errors.length > 0) {
|
if (requestValidation.errors.length > 0) {
|
||||||
const error = new SCValidationErrorResponse(
|
const error = new SCValidationErrorResponse(
|
||||||
requestValidation.errors,
|
requestValidation.errors,
|
||||||
req.app.get('isProductiveEnvironment'),
|
req.app.get('isTestEnvironment'),
|
||||||
);
|
);
|
||||||
res.status(error.statusCode);
|
res.status(error.statusCode);
|
||||||
res.json(error);
|
res.json(error);
|
||||||
@@ -101,7 +101,7 @@ export function createRoute<RETURNTYPE>(
|
|||||||
);
|
);
|
||||||
const internalServerError = new SCInternalServerErrorResponse(
|
const internalServerError = new SCInternalServerErrorResponse(
|
||||||
validationError,
|
validationError,
|
||||||
req.app.get('isProductiveEnvironment'),
|
req.app.get('isTestEnvironment'),
|
||||||
);
|
);
|
||||||
res.status(internalServerError.statusCode);
|
res.status(internalServerError.statusCode);
|
||||||
res.json(internalServerError);
|
res.json(internalServerError);
|
||||||
@@ -125,7 +125,7 @@ export function createRoute<RETURNTYPE>(
|
|||||||
// the error is not allowed so something went wrong
|
// the error is not allowed so something went wrong
|
||||||
const internalServerError = new SCInternalServerErrorResponse(
|
const internalServerError = new SCInternalServerErrorResponse(
|
||||||
error,
|
error,
|
||||||
req.app.get('isProductiveEnvironment'),
|
req.app.get('isTestEnvironment'),
|
||||||
);
|
);
|
||||||
res.status(internalServerError.statusCode);
|
res.status(internalServerError.statusCode);
|
||||||
res.json(internalServerError);
|
res.json(internalServerError);
|
||||||
@@ -139,7 +139,7 @@ export function createRoute<RETURNTYPE>(
|
|||||||
|
|
||||||
// return a SCMethodNotAllowedErrorResponse on all other HTTP methods
|
// return a SCMethodNotAllowedErrorResponse on all other HTTP methods
|
||||||
route.all((req, res) => {
|
route.all((req, res) => {
|
||||||
const error = new SCMethodNotAllowedErrorResponse(req.app.get('isProductiveEnvironment'));
|
const error = new SCMethodNotAllowedErrorResponse(req.app.get('isTestEnvironment'));
|
||||||
res.status(error.statusCode);
|
res.status(error.statusCode);
|
||||||
res.json(error);
|
res.json(error);
|
||||||
logger.warn(error);
|
logger.warn(error);
|
||||||
|
|||||||
Reference in New Issue
Block a user