diff --git a/.gitignore b/.gitignore index cc3ad90..4a518b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ +references/ ts.txt \ No newline at end of file diff --git a/api/index.js b/api/index.js index 26bf5e4..a322b6e 100644 --- a/api/index.js +++ b/api/index.js @@ -1,7 +1,6 @@ const router = require('express').Router(); -const config = require('../config-handler'); +// const config = require('../config-handler'); -// if (config().logger_mode) router.use(require('./logger')); -// router. +router.use("/v/1.0", require('./v1')); module.exports = router; \ No newline at end of file diff --git a/api/v1/create-item.js b/api/v1/create-item.js deleted file mode 100644 index e69de29..0000000 diff --git a/api/v1/errorClass.js b/api/v1/errorClass.js new file mode 100644 index 0000000..a44c0e9 --- /dev/null +++ b/api/v1/errorClass.js @@ -0,0 +1,7 @@ +module.exports = class ApiError extends Error { + constructor(message, ...args) { + super(message, ...args); + this.message = message; + this.name = "ApiError"; + } +}; \ No newline at end of file diff --git a/api/v1/index.js b/api/v1/index.js index e69de29..3fe51d6 100644 --- a/api/v1/index.js +++ b/api/v1/index.js @@ -0,0 +1,29 @@ +const router = require('express').Router(); +const response = require('./responseDecorator'); +// const config = require('../../config-handler'); + +// Подгрузка с файла +function catchError (func) { + func(); +} + +router.use('/:method_name', async (req, res, next, ...etc) => { + try { + const methodFunct = require(`./methods/${req.params.method_name}`); + response(methodFunct, req, res); + } + catch (e) { + try { + console.log(e); + const ApiError = require('./errorClass'); + catchError( + () => res.status(400).send(response((req, res) => { + throw new ApiError("METHOD_NOT_FOUNDED"); + }, req, res)) + ); + } + catch (_e) {} // Посылаем 'Cannot set headers after they are sent to the client' в.. обработку.. без обработчика. + } +}); + +module.exports = router; \ No newline at end of file diff --git a/api/v1/methods/create-item.js b/api/v1/methods/create-item.js new file mode 100644 index 0000000..7d6a97e --- /dev/null +++ b/api/v1/methods/create-item.js @@ -0,0 +1,3 @@ +module.exports = (req, res) => { + return 'method create item'; +} \ No newline at end of file diff --git a/api/v1/responseDecorator.js b/api/v1/responseDecorator.js new file mode 100644 index 0000000..bc82af6 --- /dev/null +++ b/api/v1/responseDecorator.js @@ -0,0 +1,30 @@ +const unknownError = { + error : 'UNKNOWN_ERROR' +} + +const unknownResponseFormat = 'UNKNOWN_RESPONSE_FORMAT'; + +function handlingError (funct, success, error) { + try { + success(funct()); + } + catch (e) { + // console.log('error', e); + error(e.name === 'ApiError' ? { + error : e.message + } : unknownError); + } +} + +module.exports = async (method, req, res) => { + if (req.query.response_format === 'json') { + handlingError( + () => ({ response : method(req, res) }), + (...args) => res.send(...args), + (...data) => res.status(400).json(...data) + ); + } + else { + res.status(400).send(unknownResponseFormat); + } +} \ No newline at end of file diff --git a/database.js b/database.js index e69de29..fc0219a 100644 --- a/database.js +++ b/database.js @@ -0,0 +1,3 @@ +const { Sequelize } = require('sequelize'); + +// const sequelize = new Sequelize(`postgres://user:pass@example.com:5432/dbname`); \ No newline at end of file diff --git a/db-dump/install-it.sql b/db-dump/install-it.sql new file mode 100644 index 0000000..4d00891 Binary files /dev/null and b/db-dump/install-it.sql differ diff --git a/logger.js b/logger.js index 39b7491..45e916f 100644 --- a/logger.js +++ b/logger.js @@ -1,15 +1,22 @@ const config = require('./config-handler'); function log (date, req, ip, res) { - console.log(req); + // console.log(req); + + const requestBody = !req.byteBody.toString('utf-8') ? '' : ` +~~~~~~~~~~~~~~ +[REQUEST BODY] +~~~~~~~~~~~~~~ +${req.byteBody.toString('utf-8')}`; let action = `HTTP ${req.httpVersion} ${req.method} ${req.url} ~~~~~~~~~ [HEADERS] ~~~~~~~~~ -${Object.entries(req.headers).map(([header, value]) => header + ": " + value).join('\n')}` +${Object.entries(req.headers).map(([header, value]) => header + ": " + value).join('\n')}${requestBody}`; console.log(res); - let response = '..'; - console.log(`================================\nREPORT\n================================\nIP: ${ip}\n----------------\nACTION:\n----------------\n${action}\n----------------\nRESPONSE:\n----------------\n${response}`); + // console.log(res.headers); + let response = 'NULL'; + console.log(`================================\nREPORT\n================================\n\nIP: ${ip}\n----------------\nACTION:\n----------------\n${action}\n----------------\nRESPONSE:\n----------------\n${response}`); } module.exports = async (req, res, next) => { diff --git a/package-lock.json b/package-lock.json index 0db70d4..5805d01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "dependencies": { + "body": "^5.1.0", "express": "^4.18.2", "sequelize": "^6.33.0" } @@ -49,6 +50,17 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==", + "dependencies": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + } + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -72,6 +84,23 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/body/node_modules/bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==" + }, + "node_modules/body/node_modules/raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==", + "dependencies": { + "bytes": "1", + "string_decoder": "0.10" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -111,6 +140,11 @@ "node": ">= 0.6" } }, + "node_modules/continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA==" + }, "node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -167,6 +201,14 @@ "node": ">= 0.8" } }, + "node_modules/error": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", + "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "dependencies": { + "string-template": "~0.2.1" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -561,6 +603,11 @@ } ] }, + "node_modules/safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A==" + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -738,6 +785,16 @@ "node": ">= 0.8" } }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==" + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -855,6 +912,33 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha512-chUsBxGRtuElD6fmw1gHLpvnKdVLK302peeFa9ZqAEk8TyzZ3fygLyUEDDPTJvL9+Bor0dIwn6ePOsRM2y0zQQ==", + "requires": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + }, + "dependencies": { + "bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==" + }, + "raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==", + "requires": { + "bytes": "1", + "string_decoder": "0.10" + } + } + } + }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -901,6 +985,11 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" }, + "continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha512-TF30kpKhTH8AGCG3dut0rdd/19B7Z+qCnrMoBLpyQu/2drZdNrrpcjPEoJeSVsQM+8KmWG5O56oPDjSSUsuTyA==" + }, "cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -944,6 +1033,14 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, + "error": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", + "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", + "requires": { + "string-template": "~0.2.1" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1225,6 +1322,11 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A==" + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -1339,6 +1441,16 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==" + }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", diff --git a/package.json b/package.json index 4004b21..8249bd7 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "body": "^5.1.0", "express": "^4.18.2", "sequelize": "^6.33.0" } diff --git a/server.js b/server.js index 1614f47..eba5b41 100644 --- a/server.js +++ b/server.js @@ -1,19 +1,43 @@ const express = require('express'); +const bodyHand = require('body'); const config = require('./config-handler'); const app = express(); +app.use(async (req, res, next) => { // Для добавления оригинального тела запроса + const body = bodyHand(req, res, { + limit: 9999999999, + cache: false, + encoding: 'base64' + }, (err, body) => { + if (!err) { + req.byteBody = Buffer.from(body, 'base64'); + } + else { + // console.log(err); + } + next(); + }); +}); + app.use("/api", async (rq, rs, next) => next(), require('./api')); -app.get('/admin', async (req, res) => res.send('ok')); +app.get("/admin", async (req, res) => res.send('ok')); -app.use(!config().logger_mode ? async (rq, rs, next) => next() : require('./logger'), require('./api')); +if (config().logger_mode) app.use(require('./logger'), require('./api')); // Логгирование // Подключение через HTTPS let server; if (!config().ssl.enabled) { server = app; } +else { + const https = require('https'); + server = https.createServer({ + cert : fs.readFileSync(config().ssl['public'], 'utf-8'), + key : fs.readFileSync(config().ssl['private'], 'utf-8') + }, app); +} server.listen(config().port, config().address, async (err) => { if (err) {