From bc6a835a4367f300beac0c3a727be4f1ef006f7a Mon Sep 17 00:00:00 2001 From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com> Date: Fri, 9 Feb 2024 08:29:48 +0100 Subject: [PATCH 1/8] feat: move source code and start adding logger --- tdm-be/.eslintrc | 19 +- tdm-be/app.ts | 104 ------- tdm-be/package-lock.json | 270 ++++++++++++++++-- tdm-be/package.json | 11 +- tdm-be/src/app.ts | 109 +++++++ tdm-be/{routers => src/controller}/config.ts | 0 .../controller}/data-enrichment.ts | 0 .../controller}/data-wrapper.ts | 0 .../{routers => src/controller}/traitment.ts | 2 +- tdm-be/{routers => src/controller}/webhook.ts | 0 tdm-be/src/logger.ts | 47 +++ tdm-be/{ => src}/model/Config.ts | 0 tdm-be/{ => src}/model/Request.ts | 0 tdm-be/{ => src}/model/StatusEnum.ts | 0 tdm-be/{ => src}/model/Traitment.ts | 0 tdm-be/{ => src}/service/email-sender.ts | 0 tdm-be/tsconfig.json | 31 +- 17 files changed, 444 insertions(+), 149 deletions(-) delete mode 100644 tdm-be/app.ts create mode 100644 tdm-be/src/app.ts rename tdm-be/{routers => src/controller}/config.ts (100%) rename tdm-be/{routers => src/controller}/data-enrichment.ts (100%) rename tdm-be/{routers => src/controller}/data-wrapper.ts (100%) rename tdm-be/{routers => src/controller}/traitment.ts (99%) rename tdm-be/{routers => src/controller}/webhook.ts (100%) create mode 100644 tdm-be/src/logger.ts rename tdm-be/{ => src}/model/Config.ts (100%) rename tdm-be/{ => src}/model/Request.ts (100%) rename tdm-be/{ => src}/model/StatusEnum.ts (100%) rename tdm-be/{ => src}/model/Traitment.ts (100%) rename tdm-be/{ => src}/service/email-sender.ts (100%) diff --git a/tdm-be/.eslintrc b/tdm-be/.eslintrc index 43a1d0f..e737fe2 100644 --- a/tdm-be/.eslintrc +++ b/tdm-be/.eslintrc @@ -1,9 +1,12 @@ { - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": "tsconfig.json" - }, - "extends": [ - "@draconides/eslint-config-ts" - ] -} \ No newline at end of file + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "tsconfig.json" + }, + "env": { + "node": true + }, + "extends": [ + "@draconides/eslint-config-ts" + ] +} diff --git a/tdm-be/app.ts b/tdm-be/app.ts deleted file mode 100644 index 941c8be..0000000 --- a/tdm-be/app.ts +++ /dev/null @@ -1,104 +0,0 @@ - -import express from 'express'; -import fs from 'fs'; -const path = require('path'); -const app = express(); -const cors = require("cors"); -const basicAuth = require('express-basic-auth'); // This package is used for basic authentication -const cron = require('node-cron'); - -const rawdata = fs.readFileSync('config.json', 'utf-8'); -const environment = JSON.parse(rawdata); -//Import all controllers -const dataWrapperRoute = require('./routers/data-wrapper'); -const dataEnrichmentRoute = require('./routers/data-enrichment'); -const traitmentRoute = require('./routers/traitment'); -const webhookRoute = require('./routers/webhook'); -const configRoute = require('./routers/config'); - -//Import swagger config -const swaggerFile = require('./swagger-config.json'); -const swaggerUi = require('swagger-ui-express'); - -const port = environment.port; - -// Simple example user credentials -const users = { - 'user': environment.password, -}; - -// Middleware for basic authentication -const auth = basicAuth({ - users, - challenge: true, // Sends 401 authentication challenge if credentials are missing - unauthorizedResponse: 'Authentication required.', // Message for unauthorized access -}); - -//Define backend routes -app.use(cors()) -app.use(express.json()); -app.use('/api/data-wrappers', dataWrapperRoute); -app.use('/api/data-enrichments', dataEnrichmentRoute); -app.use('/api/traitment', traitmentRoute); -app.use('/webhook', webhookRoute); - -//to secure -app.use('/config', auth, configRoute); -app.use('/swagger-config', auth, swaggerUi.serve, swaggerUi.setup(swaggerFile)); - -app.get('/', function (req, res) { - res.sendFile(path.join(__dirname, 'public', '_next', 'server', 'app', 'index.html')); -}); -app.use(express.static(path.join(__dirname, 'public'))); - -app.get('/*', function (req, res) { - res.sendFile(path.join(__dirname, 'public')); -}); - -// Middleware pour gérer les erreurs 404 (route non trouvée) -app.use((req, res, next) => { - res.status(404).send("Désolé, le fichier est introuvable, il n'a peut être pas encore été généré ou il a expiré (créé il y a plus d'une semaine)"); -}); - -const server = app.listen(port, () => { - console.log(`Running on ${port}`); -}); - -server.setTimeout(600000); // 10 minutes timeout for all routes - - - - -cron.schedule(environment.cron.schedule, () => { - const oneWeekAgo = new Date(); // Date actuelle - oneWeekAgo.setDate(oneWeekAgo.getDate() - environment.cron.deleteFileOlderThan); // Soustrait une semaine - - fs.readdir(environment.fileFolder, (err, files) => { - if (err) { - console.error('Erreur de lecture du dossier', err); - return; - } - - files.forEach((file) => { - const filePath = path.join(environment.fileFolder, file); - - fs.stat(filePath, (error, stats) => { - if (error) { - console.error('Erreur de récupération des informations sur le fichier', error); - return; - } - - // Vérifie si le fichier est plus ancien d'une semaine - if (stats.isFile() && stats.mtime < oneWeekAgo) { - fs.unlink(filePath, (unlinkError) => { - if (unlinkError) { - console.error('Erreur de suppression du fichier', unlinkError); - return; - } - console.log(`Le fichier ${file} a été supprimé.`); - }); - } - }); - }); - }); -}); \ No newline at end of file diff --git a/tdm-be/package-lock.json b/tdm-be/package-lock.json index ac25a45..e657efd 100644 --- a/tdm-be/package-lock.json +++ b/tdm-be/package-lock.json @@ -9,27 +9,28 @@ "version": "1.0.0", "license": "CeCILL", "dependencies": { - "axios": "^1.6.2", + "axios": "^1.6.7", "cors": "^2.8.5", + "express": "^4.18.2", "express-basic-auth": "^1.2.1", "multer": "^1.4.5-lts.1", "node-cron": "^3.0.3", - "nodemailer": "^6.9.7", + "nodemailer": "^6.9.9", "swagger-jsdoc": "^6.2.8", - "swagger-ui-express": "^5.0.0" + "swagger-ui-express": "^5.0.0", + "winston": "^3.11.0" }, "devDependencies": { "@draconides/eslint-config-ts": "^1.2.0", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/multer": "^1.4.11", - "@types/node": "^18.19.14", + "@types/node": "^18.19.15", "@types/node-cron": "^3.0.11", "@types/nodemailer": "^6.4.14", "@types/swagger-jsdoc": "^6.0.4", "@types/swagger-ui-express": "^4.1.6", "eslint": "^8.56.0", - "express": "^4.18.2", "ts-node": "^10.9.1", "typescript": "^5.2.2" }, @@ -69,6 +70,14 @@ "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -81,6 +90,16 @@ "node": ">=12" } }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@draconides/eslint-config-base": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@draconides/eslint-config-base/-/eslint-config-base-1.2.0.tgz", @@ -458,9 +477,9 @@ } }, "node_modules/@types/node": { - "version": "18.19.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.14.tgz", - "integrity": "sha512-EnQ4Us2rmOS64nHDWr0XqAD8DsO6f3XR6lf9UIIrZQpUzPVdN/oPuEzfDWNHSyXLvoGgjuEm/sPwFGSSs35Wtg==", + "version": "18.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.15.tgz", + "integrity": "sha512-AMZ2UWx+woHNfM11PyAEQmfSxi05jm9OlkxczuHeEqmvwPkYj6MWv44gbzDPefYOLysTOFyI3ziiy2ONmUZfpA==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -536,6 +555,11 @@ "@types/serve-static": "*" } }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", @@ -1094,6 +1118,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1112,11 +1141,11 @@ } }, "node_modules/axios": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", - "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -1257,6 +1286,15 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1272,8 +1310,38 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } }, "node_modules/combined-stream": { "version": "1.0.8", @@ -1489,6 +1557,11 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -2100,6 +2173,11 @@ "reusify": "^1.0.4" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -2177,10 +2255,15 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", @@ -2597,6 +2680,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -2758,6 +2846,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -2877,6 +2976,11 @@ "json-buffer": "3.0.1" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2926,6 +3030,27 @@ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" }, + "node_modules/logform": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz", + "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/logform/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3095,9 +3220,9 @@ } }, "node_modules/nodemailer": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz", - "integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==", + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.9.tgz", + "integrity": "sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==", "engines": { "node": ">=6.0.0" } @@ -3211,6 +3336,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/openapi-types": { "version": "12.1.3", "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", @@ -3635,6 +3768,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -3766,6 +3907,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -3780,6 +3929,14 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -4011,6 +4168,11 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4037,6 +4199,14 @@ "node": ">=0.6" } }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ts-api-utils": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", @@ -4360,6 +4530,66 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/winston": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", + "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", + "integrity": "sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/winston/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/tdm-be/package.json b/tdm-be/package.json index 9c6c7b8..780fb46 100644 --- a/tdm-be/package.json +++ b/tdm-be/package.json @@ -18,27 +18,28 @@ "author": "", "license": "CeCILL", "dependencies": { - "axios": "^1.6.2", + "axios": "^1.6.7", "cors": "^2.8.5", + "express": "^4.18.2", "express-basic-auth": "^1.2.1", "multer": "^1.4.5-lts.1", "node-cron": "^3.0.3", - "nodemailer": "^6.9.7", + "nodemailer": "^6.9.9", "swagger-jsdoc": "^6.2.8", - "swagger-ui-express": "^5.0.0" + "swagger-ui-express": "^5.0.0", + "winston": "^3.11.0" }, "devDependencies": { "@draconides/eslint-config-ts": "^1.2.0", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/multer": "^1.4.11", - "@types/node": "^18.19.14", + "@types/node": "^18.19.15", "@types/node-cron": "^3.0.11", "@types/nodemailer": "^6.4.14", "@types/swagger-jsdoc": "^6.0.4", "@types/swagger-ui-express": "^4.1.6", "eslint": "^8.56.0", - "express": "^4.18.2", "ts-node": "^10.9.1", "typescript": "^5.2.2" } diff --git a/tdm-be/src/app.ts b/tdm-be/src/app.ts new file mode 100644 index 0000000..e4ce222 --- /dev/null +++ b/tdm-be/src/app.ts @@ -0,0 +1,109 @@ +import logger, { httpLogger, cronLogger } from './logger'; +import express from 'express'; +import fs from 'node:fs'; + +const app = express(); +const configRoute = require('./controller/config'); +const dataEnrichmentRoute = require('./controller/data-enrichment'); +const dataWrapperRoute = require('./controller/data-wrapper'); +const traitmentRoute = require('./controller/traitment'); +const webhookRoute = require('./controller/webhook'); +const swaggerFile = require('../swagger-config.json'); +const cors = require('cors'); +const basicAuth = require('express-basic-auth'); // This package is used for basic authentication +const cron = require('node-cron'); + +const rawdata = fs.readFileSync('config.json', 'utf-8'); +const environment = JSON.parse(rawdata); +//Import all controllers + +//Import swagger config +const swaggerUi = require('swagger-ui-express'); +const path = require('path'); + +const port = environment.port; + +// Simple example user credentials +const users = { + user: environment.password, +}; + +// Middleware for basic authentication +const auth = basicAuth({ + users, + challenge: true, // Sends 401 authentication challenge if credentials are missing + unauthorizedResponse: 'Authentication required.', // Message for unauthorized access +}); + +app.use((req, res, next) => { + httpLogger.info(`${req.method} ${req.baseUrl} - ${req.ip}/${req.get('user-agent')}`); + next(); +}); + +//Define backend routes +app.use(cors()); +app.use(express.json()); +app.use('/api/data-wrappers', dataWrapperRoute); +app.use('/api/data-enrichments', dataEnrichmentRoute); +app.use('/api/traitment', traitmentRoute); +app.use('/webhook', webhookRoute); + +//to secure +app.use('/config', auth, configRoute); +app.use('/swagger-config', auth, swaggerUi.serve, swaggerUi.setup(swaggerFile)); + +app.get('/', function (req, res) { + res.sendFile(path.join(__dirname, 'public', '_next', 'server', 'app', 'index.html')); +}); +app.use(express.static(path.join(__dirname, 'public'))); + +app.get('/*', function (req, res) { + res.sendFile(path.join(__dirname, 'public')); +}); + +// Middleware pour gérer les erreurs 404 (route non trouvée) +app.use((req, res, next) => { + res.status(404).send( + "Désolé, le fichier est introuvable, il n'a peut être pas encore été généré ou il a expiré (créé il y a plus d'une semaine)", + ); +}); + +const server = app.listen(port, () => { + logger.debug(`Running on ${port}`); +}); + +server.setTimeout(600000); // 10 minutes timeout for all routes + +cron.schedule(environment.cron.schedule, () => { + const oneWeekAgo = new Date(); // Date actuelle + oneWeekAgo.setDate(oneWeekAgo.getDate() - environment.cron.deleteFileOlderThan); // Soustrait une semaine + + fs.readdir(environment.fileFolder, (err, files) => { + if (err) { + cronLogger.error('Erreur de lecture du dossier', err); + return; + } + + files.forEach((file) => { + const filePath = path.join(environment.fileFolder, file); + + fs.stat(filePath, (error, stats) => { + if (error) { + cronLogger.error('Erreur de récupération des informations sur le fichier', error); + return; + } + + // Vérifie si le fichier est plus ancien d'une semaine + if (stats.isFile() && stats.mtime < oneWeekAgo) { + fs.unlink(filePath, (unlinkError) => { + if (unlinkError) { + cronLogger.error('Erreur de suppression du fichier', unlinkError); + return; + } + cronLogger.info(`Le fichier ${file} a été supprimé.`); + }); + } + }); + }); + }); +}); diff --git a/tdm-be/routers/config.ts b/tdm-be/src/controller/config.ts similarity index 100% rename from tdm-be/routers/config.ts rename to tdm-be/src/controller/config.ts diff --git a/tdm-be/routers/data-enrichment.ts b/tdm-be/src/controller/data-enrichment.ts similarity index 100% rename from tdm-be/routers/data-enrichment.ts rename to tdm-be/src/controller/data-enrichment.ts diff --git a/tdm-be/routers/data-wrapper.ts b/tdm-be/src/controller/data-wrapper.ts similarity index 100% rename from tdm-be/routers/data-wrapper.ts rename to tdm-be/src/controller/data-wrapper.ts diff --git a/tdm-be/routers/traitment.ts b/tdm-be/src/controller/traitment.ts similarity index 99% rename from tdm-be/routers/traitment.ts rename to tdm-be/src/controller/traitment.ts index 7c0f9bc..b35f9db 100644 --- a/tdm-be/routers/traitment.ts +++ b/tdm-be/src/controller/traitment.ts @@ -1,4 +1,4 @@ -import environment from '../config.json'; +import environment from '../../config.json'; import { StatusEnum } from '../model/StatusEnum'; import { sendEmail } from '../service/email-sender'; import axios from 'axios'; diff --git a/tdm-be/routers/webhook.ts b/tdm-be/src/controller/webhook.ts similarity index 100% rename from tdm-be/routers/webhook.ts rename to tdm-be/src/controller/webhook.ts diff --git a/tdm-be/src/logger.ts b/tdm-be/src/logger.ts new file mode 100644 index 0000000..6edcf48 --- /dev/null +++ b/tdm-be/src/logger.ts @@ -0,0 +1,47 @@ +import { createLogger, format, transports } from 'winston'; +import type { Logger } from 'winston'; + +/** + * Create a winston logger with an associated label + * @param name Label use with the logger + */ +const create = (name: string): Logger => { + return createLogger({ + format: format.combine( + format.label({ label: name }), + format.timestamp(), + format.printf((info) => { + return `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`; + }), + ), + transports: [ + new transports.Console(), + new transports.File({ + filename: name === 'default' ? 'logs/combined.log' : `logs/${name}-combined.log`, + }), + new transports.File({ + level: 'debug', + filename: name === 'default' ? 'logs/debug.log' : `logs/${name}-debug.log`, + }), + ], + }); +}; + +/** + * Default logger, the logger can be used for general propos + */ +export const defaultLogger: Logger = create('default'); +/** + * Logger use by the express http server + */ +export const httpLogger: Logger = create('http'); +/** + * Logger use to log mail process + */ +export const mailLogger: Logger = create('mail'); +/** + * Logger use to log cron process + */ +export const cronLogger: Logger = create('cron'); + +export default defaultLogger; diff --git a/tdm-be/model/Config.ts b/tdm-be/src/model/Config.ts similarity index 100% rename from tdm-be/model/Config.ts rename to tdm-be/src/model/Config.ts diff --git a/tdm-be/model/Request.ts b/tdm-be/src/model/Request.ts similarity index 100% rename from tdm-be/model/Request.ts rename to tdm-be/src/model/Request.ts diff --git a/tdm-be/model/StatusEnum.ts b/tdm-be/src/model/StatusEnum.ts similarity index 100% rename from tdm-be/model/StatusEnum.ts rename to tdm-be/src/model/StatusEnum.ts diff --git a/tdm-be/model/Traitment.ts b/tdm-be/src/model/Traitment.ts similarity index 100% rename from tdm-be/model/Traitment.ts rename to tdm-be/src/model/Traitment.ts diff --git a/tdm-be/service/email-sender.ts b/tdm-be/src/service/email-sender.ts similarity index 100% rename from tdm-be/service/email-sender.ts rename to tdm-be/src/service/email-sender.ts diff --git a/tdm-be/tsconfig.json b/tdm-be/tsconfig.json index 21d0fba..0c5f655 100644 --- a/tdm-be/tsconfig.json +++ b/tdm-be/tsconfig.json @@ -1,14 +1,23 @@ { "compilerOptions": { - "target": "es6", - "module": "commonjs", - "outDir": "./dist", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true + "target": "es6", + "module": "commonjs", + "lib": [ + "ESNext" + ], + "outDir": "./dist", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, }, - "include": ["**/*.ts"], - "exclude": ["node_modules", "dist"] - } \ No newline at end of file + "include": [ + "**/*.ts" + ], + "exclude": [ + "node_modules", + "dist" + ] +} From 991d0c2cb78f24735c545a6b72969f42aab3529b Mon Sep 17 00:00:00 2001 From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com> Date: Fri, 9 Feb 2024 08:41:26 +0100 Subject: [PATCH 2/8] build: add missing folder creation in Dockerfile --- Dockerfile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index d99df86..b667e4a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -79,12 +79,15 @@ COPY --chown=daemon:daemon --from=express-build /app/swagger.json /app/ COPY --chown=daemon:daemon --from=express-build /app/config.json /app/ COPY --chown=daemon:daemon --from=express-build /app/dist /app/ -# Copy front-end files from the build container and create the required folder +# Copy front-end files from the build container COPY --chown=daemon:daemon --from=react-build /app/.next /app/public/_next/ + +# Create the required folder RUN mkdir /app/public/downloads RUN mkdir /app/uploads +RUN mkdir /app/logs # Start the application EXPOSE 3000 ENV NODE_ENV="production" -CMD ["npm", "start"] \ No newline at end of file +CMD ["npm", "start"] From 72716eacd46857a43f36187d0ac420f2fa1cb5f9 Mon Sep 17 00:00:00 2001 From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com> Date: Fri, 9 Feb 2024 12:14:26 +0100 Subject: [PATCH 3/8] refactor: convert console to logger and correctly handle config --- Dockerfile | 2 +- tdm-be/{config.json => config/default.json} | 0 tdm-be/package-lock.json | 30 ++++++++++ tdm-be/package.json | 2 + tdm-be/src/app.ts | 5 +- tdm-be/src/controller/config.ts | 29 ++++++---- tdm-be/src/controller/data-enrichment.ts | 44 +++++++------- tdm-be/src/controller/data-wrapper.ts | 49 ++++++++-------- tdm-be/src/controller/traitment.ts | 52 ++++++----------- tdm-be/src/controller/webhook.ts | 52 ++++++----------- tdm-be/src/lib/config.ts | 39 +++++++++++++ tdm-be/src/{ => lib}/logger.ts | 0 tdm-be/src/model/Config.ts | 63 +++++++++++---------- tdm-be/src/model/Request.ts | 18 +++--- tdm-be/src/model/StatusEnum.ts | 4 +- tdm-be/src/model/Traitment.ts | 18 +++--- tdm-be/src/service/email-sender.ts | 50 ++++++++-------- tdm-be/tsconfig.json | 7 ++- 18 files changed, 254 insertions(+), 210 deletions(-) rename tdm-be/{config.json => config/default.json} (100%) create mode 100644 tdm-be/src/lib/config.ts rename tdm-be/src/{ => lib}/logger.ts (100%) diff --git a/Dockerfile b/Dockerfile index b667e4a..2a25dcc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,7 +58,7 @@ FROM node:18.19-bullseye-slim AS application # Add ezmaster config file RUN echo '{ \ "httpPort": 3000, \ - "configPath": "/app/config.json", \ + "configPath": "/app/config/default.json", \ "dataPath": "/app" \ }' > /etc/ezmaster.json diff --git a/tdm-be/config.json b/tdm-be/config/default.json similarity index 100% rename from tdm-be/config.json rename to tdm-be/config/default.json diff --git a/tdm-be/package-lock.json b/tdm-be/package-lock.json index e657efd..5839e02 100644 --- a/tdm-be/package-lock.json +++ b/tdm-be/package-lock.json @@ -10,6 +10,7 @@ "license": "CeCILL", "dependencies": { "axios": "^1.6.7", + "config": "^3.3.11", "cors": "^2.8.5", "express": "^4.18.2", "express-basic-auth": "^1.2.1", @@ -22,6 +23,7 @@ }, "devDependencies": { "@draconides/eslint-config-ts": "^1.2.0", + "@types/config": "^3.3.3", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/multer": "^1.4.11", @@ -401,6 +403,12 @@ "@types/node": "*" } }, + "node_modules/@types/config": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@types/config/-/config-3.3.3.tgz", + "integrity": "sha512-BB8DBAud88EgiAKlz8WQStzI771Kb6F3j4dioRJ4GD+tP4tzcZyMlz86aXuZT4s9hyesFORehMQE6eqtA5O+Vg==", + "dev": true + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -1381,6 +1389,28 @@ "typedarray": "^0.0.6" } }, + "node_modules/config": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/config/-/config-3.3.11.tgz", + "integrity": "sha512-Dhn63ZoWCW5EMg4P0Sl/XNsj/7RLiUIA1x1npCy+m2cRwRHzLnt3UtYtxRDMZW/6oOMdWhCzaGYkOcajGgrAOA==", + "dependencies": { + "json5": "^2.2.3" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/config/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", diff --git a/tdm-be/package.json b/tdm-be/package.json index 780fb46..3eea5f6 100644 --- a/tdm-be/package.json +++ b/tdm-be/package.json @@ -19,6 +19,7 @@ "license": "CeCILL", "dependencies": { "axios": "^1.6.7", + "config": "^3.3.11", "cors": "^2.8.5", "express": "^4.18.2", "express-basic-auth": "^1.2.1", @@ -31,6 +32,7 @@ }, "devDependencies": { "@draconides/eslint-config-ts": "^1.2.0", + "@types/config": "^3.3.3", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/multer": "^1.4.11", diff --git a/tdm-be/src/app.ts b/tdm-be/src/app.ts index e4ce222..90c00d1 100644 --- a/tdm-be/src/app.ts +++ b/tdm-be/src/app.ts @@ -1,4 +1,5 @@ -import logger, { httpLogger, cronLogger } from './logger'; +import environment from './lib/config'; +import logger, { httpLogger, cronLogger } from './lib/logger'; import express from 'express'; import fs from 'node:fs'; @@ -13,8 +14,6 @@ const cors = require('cors'); const basicAuth = require('express-basic-auth'); // This package is used for basic authentication const cron = require('node-cron'); -const rawdata = fs.readFileSync('config.json', 'utf-8'); -const environment = JSON.parse(rawdata); //Import all controllers //Import swagger config diff --git a/tdm-be/src/controller/config.ts b/tdm-be/src/controller/config.ts index 5fee452..2dd0b35 100644 --- a/tdm-be/src/controller/config.ts +++ b/tdm-be/src/controller/config.ts @@ -1,5 +1,7 @@ +import logger from '../lib/logger'; import express from 'express'; -var config = require('../model/Config'); + +const config = require('../model/Config'); const router = express.Router(); @@ -21,14 +23,14 @@ const router = express.Router(); * $ref: '#/components/schemas/SwaggerApi' * example: [{'url':'https://data-computer.services.istex.fr', 'retrieveUrl':'/v1/retrieve', 'tags':[{'name':'data-computer','excluded':['/v1/collect','/v1/retrieve','/v1/mock-error-async','/v1/mock-error-sync']}]}] * mailSuccess: - * type: + * type: * $ref: '#/components/schemas/Mail' * example: {'subject':'Objet du mail succès', 'text':'Vous pouvez télécharger le fichier enrichi à l'adresse ci-dessous' } * mailError: - * type: + * type: * $ref: '#/components/schemas/Mail' * example: {'subject':'Objet du mail d'erreur', 'text':'Une erreur s'est produite lors de l'enrichissement' } - * + * * SwaggerApi: * type: object * properties: @@ -59,7 +61,7 @@ const router = express.Router(); * type: string * text: * type: string - * + * */ /** @@ -92,13 +94,16 @@ const router = express.Router(); * type: string * description: Error message describing the issue */ -router.post('/set', (req, res) => { - config.setConfig(req.body); - res.status(200).json({ message: 'Config data updated successfully', config: config.getConfig() }); -}, (error) => { - console.log(error); -}); - +router.post( + '/set', + (req, res) => { + config.setConfig(req.body); + res.status(200).json({ message: 'Config data updated successfully', config: config.getConfig() }); + }, + (error) => { + logger.error(error); + }, +); /** * @swagger diff --git a/tdm-be/src/controller/data-enrichment.ts b/tdm-be/src/controller/data-enrichment.ts index 485235b..81a5e79 100644 --- a/tdm-be/src/controller/data-enrichment.ts +++ b/tdm-be/src/controller/data-enrichment.ts @@ -1,8 +1,9 @@ -import { Request } from '../model/Request'; -import express from 'express'; import axios from 'axios'; +import express from 'express'; import type { Config } from '../model/Config'; -var singleton: Config = require('../model/Config'); +import type { Request } from '../model/Request'; + +const singleton: Config = require('../model/Config'); const router = express.Router(); /** @@ -61,25 +62,26 @@ const router = express.Router(); //Route to access all enrichments in the istex api due to config set router.get('/list', async (req, res) => { + const results = await Promise.all( + singleton.getConfig().enrichments?.map((enrichment) => axios.get(enrichment.url)), + ); - const results = await Promise.all( - singleton.getConfig().enrichments?.map((enrichment) => axios.get(enrichment.url)) - ); - - const requests = results.flatMap(res => { - const tags = singleton.getConfig().enrichments?.find((enrichment) => enrichment.url === res.config.url)?.tags; - return Object.entries(res.data.paths) - .filter((path: any) => tags?.some((t) => path[1].post?.tags?.includes(t.name) && t.excluded?.indexOf(path[0]) === -1)) - .map((path: any) => { - return { - label: `${path[1].post.summary} (${path[0]})`, - description: path[1].post.description, - url: `${res.data.servers[0].variables.scheme.default}://${res.data.servers[0].variables.hostname.default}${path[0]}`, - parameters: path[1].post?.parameters?.map((param: any) => param.name) - }; - }) - }); - res.json(requests); + const requests = results.flatMap((res) => { + const tags = singleton.getConfig().enrichments?.find((enrichment) => enrichment.url === res.config.url)?.tags; + return Object.entries(res.data.paths) + .filter((path: any) => + tags?.some((t) => path[1].post?.tags?.includes(t.name) && t.excluded?.indexOf(path[0]) === -1), + ) + .map((path: any) => { + return { + label: `${path[1].post.summary} (${path[0]})`, + description: path[1].post.description, + url: `${res.data.servers[0].variables.scheme.default}://${res.data.servers[0].variables.hostname.default}${path[0]}`, + parameters: path[1].post?.parameters?.map((param: any) => param.name), + }; + }); + }); + res.json(requests); }); module.exports = router; diff --git a/tdm-be/src/controller/data-wrapper.ts b/tdm-be/src/controller/data-wrapper.ts index a12b34b..f1775cb 100644 --- a/tdm-be/src/controller/data-wrapper.ts +++ b/tdm-be/src/controller/data-wrapper.ts @@ -1,10 +1,10 @@ -import express from 'express'; import axios from 'axios'; -import { Parameter, Request } from '../model/Request'; +import express from 'express'; +import type { Config } from '../model/Config'; +import type { Parameter, Request } from '../model/Request'; const router = express.Router(); -import type { Config } from '../model/Config'; -var singleton: Config = require('../model/Config'); +const singleton: Config = require('../model/Config'); /** * @swagger @@ -24,26 +24,29 @@ var singleton: Config = require('../model/Config'); */ //Route to access all wrapper available due to config set router.get('/list', async (req, res) => { - const results = await Promise.all( - singleton.getConfig().wrappers?.map((wrapper) => axios.get(wrapper.url)) - ); + const results = await Promise.all(singleton.getConfig().wrappers?.map((wrapper) => axios.get(wrapper.url))); - const requests = results.flatMap(res => { - const tags = singleton.getConfig().wrappers?.find((wrapper) => wrapper.url === res.config.url)?.tags; - return Object.entries(res.data.paths) - .filter((path: any) => tags?.some((t) => path[1].post?.tags?.includes(t.name) && t.excluded?.indexOf(path[0]) === -1)) - .map((path: any[]) => { - console.log(); - return { - label: `${path[1].post.summary} (${path[0]})`, - description: path[1].post.description, - fileType: Object.entries(path[1].post.requestBody.content).map((filetype) => filetype[0]), - url: `${res.data.servers[0].variables.scheme.default}://${res.data.servers[0].variables.hostname.default}${path[0]}`, - parameters: path[1].post?.parameters?.map((param: any) => { return { name: param.name, displayName: param.description + ` (par défaut ${param.name})` } }).filter((param: Parameter) => param.name === 'value'), - }; - }) - }); - res.json(requests); + const requests = results.flatMap((res) => { + const tags = singleton.getConfig().wrappers?.find((wrapper) => wrapper.url === res.config.url)?.tags; + return Object.entries(res.data.paths) + .filter((path: any) => + tags?.some((t) => path[1].post?.tags?.includes(t.name) && t.excluded?.indexOf(path[0]) === -1), + ) + .map((path: any[]) => { + return { + label: `${path[1].post.summary} (${path[0]})`, + description: path[1].post.description, + fileType: Object.entries(path[1].post.requestBody.content).map((filetype) => filetype[0]), + url: `${res.data.servers[0].variables.scheme.default}://${res.data.servers[0].variables.hostname.default}${path[0]}`, + parameters: path[1].post?.parameters + ?.map((param: any) => { + return { name: param.name, displayName: param.description + ` (par défaut ${param.name})` }; + }) + .filter((param: Parameter) => param.name === 'value'), + }; + }); + }); + res.json(requests); }); module.exports = router; diff --git a/tdm-be/src/controller/traitment.ts b/tdm-be/src/controller/traitment.ts index b35f9db..e9b9671 100644 --- a/tdm-be/src/controller/traitment.ts +++ b/tdm-be/src/controller/traitment.ts @@ -1,4 +1,5 @@ -import environment from '../../config.json'; +import environment from '../lib/config'; +import logger from '../lib/logger'; import { StatusEnum } from '../model/StatusEnum'; import { sendEmail } from '../service/email-sender'; import axios from 'axios'; @@ -68,12 +69,8 @@ router.post( const traitment: Traitment = req.body; currentTraitments.push(traitment); const url = traitment.wrapper?.url ? traitment.wrapper?.url : ''; - const urlEnrichment = traitment.enrichment?.url - ? traitment.enrichment?.url - : ''; - const fileData = fs.readFileSync( - `${environment.fileFolder}${traitment.file}`, - ); + const urlEnrichment = traitment.enrichment?.url ? traitment.enrichment?.url : ''; + const fileData = fs.readFileSync(`${environment.fileFolder}${traitment.file}`); traitment.timestamp = new Date().getTime(); traitment.status = StatusEnum.WRAPPER_RUNNING; res.send({ @@ -85,17 +82,13 @@ router.post( subject: 'Votre traitement a bien démarré', text: `Un suivi est disponible à l\'url http://${req.hostname}?id=${traitment.timestamp}`, }).then(() => { - console.info( - `${new Date().toISOString()}mail envoyer pour début de traitement`, - ); + logger.info('mail envoyer pour début de traitement'); }); axios .post(url, fileData, { responseType: 'arraybuffer', params: { - value: traitment.wrapper.parameters?.find( - (p) => p.name === 'value', - )?.value, + value: traitment.wrapper.parameters?.find((p) => p.name === 'value')?.value, }, timeout: 600000, }) @@ -104,18 +97,14 @@ router.post( const bin: Buffer = Buffer.from(wrapperRes.data, 'binary'); fs.writeFileSync(environment.dumpFile, bin); const fd = fs.readFileSync(environment.dumpFile); - console.log(`Wrapper Done for ${traitment.timestamp}`); + logger.info(`Wrapper Done for ${traitment.timestamp}`); const conf = { headers: { 'X-Webhook-Success': `${ - environment.hosts.internal.isHttps - ? 'https' - : 'http' + environment.hosts.internal.isHttps ? 'https' : 'http' }://${environment.hosts.internal.host}/webhook/success?id=${traitment.timestamp}`, 'X-Webhook-Failure': `${ - environment.hosts.internal.isHttps - ? 'https' - : 'http' + environment.hosts.internal.isHttps ? 'https' : 'http' }://${environment.hosts.internal.host}/webhook/failure?id=${traitment.timestamp}`, }, timeout: 600000, @@ -124,32 +113,27 @@ router.post( axios.post(urlEnrichment, fd, conf).then( (enrichmentRes) => { traitment.status = StatusEnum.WAITING_WEBHOOK; - console.log( - `Traitment Done for ${traitment.timestamp}`, - ); - traitment.retrieveValue = - enrichmentRes.data[0].value; + logger.info(`Traitment Done for ${traitment.timestamp}`); + traitment.retrieveValue = enrichmentRes.data[0].value; }, (error) => { traitment.status = StatusEnum.TRAITMENT_ERROR; - console.log( - `Traitment Error for ${traitment.timestamp}`, - ); - console.log(error); + logger.error(`Traitment Error for ${traitment.timestamp}`); + logger.error(error); res.status(500).send(error.response.data.message); }, ); }, (error) => { traitment.status = StatusEnum.WRAPPER_ERROR; - console.log(`Wrapper Error for ${traitment.timestamp}`); - console.log(error); + logger.error(`Wrapper Error for ${traitment.timestamp}`); + logger.error(error); res.status(500).send(error.message); }, ); }, (error) => { - console.log(error); + logger.error(error); }, ); @@ -225,9 +209,7 @@ router.post('/upload', upload.single('file'), (req: any, res: Response) => { //Route to retrieve traitment status router.get('/status', (req, res) => { const { id } = req.query; - const traitment: Traitment = currentTraitments.filter( - (t) => t.timestamp + '' === id, - )[0]; + const traitment: Traitment = currentTraitments.filter((t) => t.timestamp + '' === id)[0]; let status: StatusEnum = StatusEnum.UNKNOWN; if (traitment) { status = traitment.status; diff --git a/tdm-be/src/controller/webhook.ts b/tdm-be/src/controller/webhook.ts index 8c6a855..4f39eda 100644 --- a/tdm-be/src/controller/webhook.ts +++ b/tdm-be/src/controller/webhook.ts @@ -1,3 +1,4 @@ +import logger from '../lib/logger'; import { StatusEnum } from '../model/StatusEnum'; import { sendEmail } from '../service/email-sender'; import axios from 'axios'; @@ -18,33 +19,22 @@ router.post( '/success', (req, res) => { const { id } = req.query; - const traitment: Traitment = currentTraitments.filter( - (t) => t.timestamp + '' === id, - )[0]; + const traitment: Traitment = currentTraitments.filter((t) => t.timestamp + '' === id)[0]; const enrichment = config.enrichments.filter( - (enrichment: SwaggerApi) => - traitment.enrichment.url.indexOf(enrichment.url) > -1, + (enrichment: SwaggerApi) => traitment.enrichment.url.indexOf(enrichment.url) > -1, )[0]; if (traitment) { axios - .post( - enrichment.url + enrichment.retrieveUrl, - [{ value: traitment.retrieveValue }], - { responseType: 'arraybuffer' }, - ) + .post(enrichment.url + enrichment.retrieveUrl, [{ value: traitment.retrieveValue }], { + responseType: 'arraybuffer', + }) .then( (retrieveRes) => { traitment.status = StatusEnum.FINISHED; // Process the payload as needed - const bin: Buffer = Buffer.from( - retrieveRes.data, - 'binary', - ); - fs.writeFileSync( - `public/downloads/${traitment.timestamp}.tar.gz`, - bin, - ); - console.log('mail sent to smtp'); + const bin: Buffer = Buffer.from(retrieveRes.data, 'binary'); + fs.writeFileSync(`public/downloads/${traitment.timestamp}.tar.gz`, bin); + logger.info('mail sent to smtp'); const mailOptions: EmailOptions = { to: traitment.mail, subject: config.mailSuccess.subject, @@ -56,21 +46,17 @@ router.post( res.send('Email envoyé'); }, (error) => { - console.log(error); + logger.error(error); res.status(500).send('Error retrieving file'); }, ); } else { - console.log( - `This traitment doesn't exist on current process id=${id}`, - ); - res.status(404).send( - `This traitment doesn't exist on current process id=${id}`, - ); + logger.error(`This traitment doesn't exist on current process id=${id}`); + res.status(404).send(`This traitment doesn't exist on current process id=${id}`); } }, (error) => { - console.log(error); + logger.error(error); }, ); @@ -79,16 +65,12 @@ router.post( '/failure', (req, res) => { const { id } = req.query; - const traitment: Traitment = currentTraitments.filter( - (traitment) => traitment.timestamp === id, - )[0]; + const traitment: Traitment = currentTraitments.filter((traitment) => traitment.timestamp === id)[0]; traitment.status = StatusEnum.FINISHED_ERROR; if (traitment) { - currentTraitments = currentTraitments.filter( - (t) => t.timestamp !== traitment.timestamp, - ); + currentTraitments = currentTraitments.filter((t) => t.timestamp !== traitment.timestamp); // Process the payload as needed - console.log('Received webhook error:', id); + logger.info('Received webhook error:', id); const mailOptions: EmailOptions = { to: traitment.mail, subject: config.mailError.subject, @@ -98,7 +80,7 @@ router.post( } }, (error) => { - console.log(error); + logger.error(error); }, ); diff --git a/tdm-be/src/lib/config.ts b/tdm-be/src/lib/config.ts new file mode 100644 index 0000000..92d22a0 --- /dev/null +++ b/tdm-be/src/lib/config.ts @@ -0,0 +1,39 @@ +import config from 'config'; + +type Host = { + host: string; + isHttps: boolean; +}; + +type SMTP = { + host: string; + port: number; + auth: { + user: string; + pass: string; + }; + secure: boolean; + tls: { + ignore: boolean; + rejectUnauthorized: false; + }; +}; + +type Config = { + port: number; + password: string; + hosts: { + internal: Host; + external: Host; + }; + smtp: SMTP; + fileFolder: string; + dumpFile: string; + finalFile: string; + cron: { + schedule: string; + deleteFileOlderThan: number; + }; +}; + +export default config as unknown as Config; diff --git a/tdm-be/src/logger.ts b/tdm-be/src/lib/logger.ts similarity index 100% rename from tdm-be/src/logger.ts rename to tdm-be/src/lib/logger.ts diff --git a/tdm-be/src/model/Config.ts b/tdm-be/src/model/Config.ts index 69e4cf2..64637b1 100644 --- a/tdm-be/src/model/Config.ts +++ b/tdm-be/src/model/Config.ts @@ -1,20 +1,21 @@ -import { readFileSync } from 'node:fs' +import logger from '../lib/logger'; +import { readFileSync } from 'node:fs'; import { writeFile } from 'node:fs/promises'; export class SwaggerApi { - url: string = ''; + url = ''; retrieveUrl?: string; tags: Tag[] = []; } export class Tag { - name: string = ''; + name = ''; excluded?: string[] = []; } export class Mail { - subject: string = ''; - text: string = ''; + subject = ''; + text = ''; } type ConfigType = { @@ -22,7 +23,7 @@ type ConfigType = { enrichments: SwaggerApi[]; mailSuccess: Mail; mailError: Mail; -} +}; export class Config { private readonly config: ConfigType; @@ -32,7 +33,7 @@ export class Config { const rawLocalConfig = readFileSync('dynamic-config.json', 'utf-8'); localConfig = JSON.parse(rawLocalConfig); } catch (e) { - console.error('No dynamic config file found') + logger.error('No dynamic config file found'); localConfig = {}; } @@ -40,43 +41,43 @@ export class Config { wrappers: localConfig.wrappers ?? [ { url: 'https://data-wrapper.services.istex.fr', - tags: [{ - name: 'data-wrapper', - excluded: [] - }] - } + tags: [ + { + name: 'data-wrapper', + excluded: [], + }, + ], + }, ], enrichments: localConfig.enrichments ?? [ { url: 'https://data-computer.services.istex.fr', retrieveUrl: '/v1/retrieve', - tags: [{ - name: 'data-computer', - excluded: ['/v1/collect', '/v1/retrieve', '/v1/mock-error-async', '/v1/mock-error-sync'] - }] - } + tags: [ + { + name: 'data-computer', + excluded: ['/v1/collect', '/v1/retrieve', '/v1/mock-error-async', '/v1/mock-error-sync'], + }, + ], + }, ], mailSuccess: localConfig.mailSuccess ?? { subject: 'Objet du mail succès', - text: 'Vous pouvez télécharger le fichier enrichi à l\'adresse ci-dessous' + text: "Vous pouvez télécharger le fichier enrichi à l'adresse ci-dessous", }, mailError: localConfig.mailError ?? { - subject: 'Objet du mail d\'erreur', - text: 'Une erreur s\'est produite lors de l\'enrichissement' - } - } - console.info('Dynamic config loaded'); + subject: "Objet du mail d'erreur", + text: "Une erreur s'est produite lors de l'enrichissement", + }, + }; + logger.info('Dynamic config loaded'); this.saveConfig(); } private saveConfig() { - writeFile( - 'dynamic-config.json', - JSON.stringify(this.config), - 'utf-8' - ).then(() => { - console.info('Dynamic config successfully written to disk') - }) + writeFile('dynamic-config.json', JSON.stringify(this.config), 'utf-8').then(() => { + logger.info('Dynamic config successfully written to disk'); + }); } getConfig(): ConfigType { @@ -111,6 +112,6 @@ export class Config { } } -const singleton = new Config() +const singleton = new Config(); module.exports = singleton; diff --git a/tdm-be/src/model/Request.ts b/tdm-be/src/model/Request.ts index 6548160..bdb34c0 100644 --- a/tdm-be/src/model/Request.ts +++ b/tdm-be/src/model/Request.ts @@ -1,13 +1,13 @@ export class Request { - label?: string; - url: string = ''; - parameters?: Parameter[]; - fileType?: string[]; - description?: string; + label?: string; + url = ''; + parameters?: Parameter[]; + fileType?: string[]; + description?: string; } export class Parameter { - displayName?: string; - name?: string; - value?: string; -} \ No newline at end of file + displayName?: string; + name?: string; + value?: string; +} diff --git a/tdm-be/src/model/StatusEnum.ts b/tdm-be/src/model/StatusEnum.ts index 7a179f5..1cab3ad 100644 --- a/tdm-be/src/model/StatusEnum.ts +++ b/tdm-be/src/model/StatusEnum.ts @@ -6,5 +6,5 @@ export enum StatusEnum { WAITING_WEBHOOK, FINISHED, FINISHED_ERROR, - UNKNOWN -} \ No newline at end of file + UNKNOWN, +} diff --git a/tdm-be/src/model/Traitment.ts b/tdm-be/src/model/Traitment.ts index a83be33..0d2a7e5 100644 --- a/tdm-be/src/model/Traitment.ts +++ b/tdm-be/src/model/Traitment.ts @@ -1,18 +1,16 @@ -import { Request } from './Request'; import { StatusEnum } from './StatusEnum'; +import type { Request } from './Request'; export class Traitment { - wrapper: Request = { url: '' }; - enrichment: Request = { url: '' }; - mail: string = ''; - file: string = ''; - timestamp?: number; - retrieveValue?: string; - status: StatusEnum = StatusEnum.UNKNOWN; + wrapper: Request = { url: '' }; + enrichment: Request = { url: '' }; + mail = ''; + file = ''; + timestamp?: number; + retrieveValue?: string; + status: StatusEnum = StatusEnum.UNKNOWN; } - - const currentTraitments: Traitment[] = []; module.exports = currentTraitments; diff --git a/tdm-be/src/service/email-sender.ts b/tdm-be/src/service/email-sender.ts index 0e72532..90eac08 100644 --- a/tdm-be/src/service/email-sender.ts +++ b/tdm-be/src/service/email-sender.ts @@ -1,35 +1,35 @@ +import environment from '../lib/config'; +import { mailLogger } from '../lib/logger'; import nodemailer from 'nodemailer'; -import fs from 'fs'; -const rawdata = fs.readFileSync('config.json', 'utf-8'); -const environment = JSON.parse(rawdata); -export interface EmailOptions { - to: string; - subject: string; - text: string; - attachments?: any[]; -} + +export type EmailOptions = { + to: string; + subject: string; + text: string; + attachments?: any[]; +}; async function sendEmail(options: EmailOptions): Promise { - try { - const smtpConfig = environment.smtp; + try { + const smtpConfig = environment.smtp; - const transporter = nodemailer.createTransport(smtpConfig); + const transporter = nodemailer.createTransport(smtpConfig); - const mailOptions = { - ...options, - from: 'noreply@inist.fr' - }; + const mailOptions = { + ...options, + from: 'noreply@inist.fr', + }; - const info = await transporter.sendMail(mailOptions); + const info = await transporter.sendMail(mailOptions); - transporter.close(); + transporter.close(); - console.log('Email sent:', info.response); - return info; - } catch (error) { - console.error('Error sending email:', error); - throw error; - } + mailLogger.info('Email sent:', info.response); + return info; + } catch (error) { + mailLogger.error('Error sending email:', error); + throw error; + } } -export { sendEmail }; \ No newline at end of file +export { sendEmail }; diff --git a/tdm-be/tsconfig.json b/tdm-be/tsconfig.json index 0c5f655..9875f54 100644 --- a/tdm-be/tsconfig.json +++ b/tdm-be/tsconfig.json @@ -5,16 +5,17 @@ "lib": [ "ESNext" ], - "outDir": "./dist", + "outDir": "dist", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, - "allowSyntheticDefaultImports": true, + "allowSyntheticDefaultImports": true }, "include": [ - "**/*.ts" + "src/**/*.ts", + "config/config.json" ], "exclude": [ "node_modules", From bd95bdcc4b226707443dc502b76618679e902fae Mon Sep 17 00:00:00 2001 From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:10:40 +0100 Subject: [PATCH 4/8] build: fix file copy --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 2a25dcc..a9cbe43 100644 --- a/Dockerfile +++ b/Dockerfile @@ -76,7 +76,7 @@ COPY --chown=daemon:daemon --from=express-build /app/package-lock.json /app/ COPY --chown=daemon:daemon --from=node-modules /app/node_modules /app/node_modules/ COPY --chown=daemon:daemon --from=express-build /app/swagger-config.json /app/ COPY --chown=daemon:daemon --from=express-build /app/swagger.json /app/ -COPY --chown=daemon:daemon --from=express-build /app/config.json /app/ +COPY --chown=daemon:daemon --from=express-build /app/config/default.json /app/config/ COPY --chown=daemon:daemon --from=express-build /app/dist /app/ # Copy front-end files from the build container From 0e4d0e474f929ba5918121845b09dcd6a5b2a457 Mon Sep 17 00:00:00 2001 From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:54:24 +0100 Subject: [PATCH 5/8] build: move swagger files --- tdm-be/package.json | 2 +- tdm-be/src/app.ts | 2 +- tdm-be/{ => src/swagger}/swagger-config.json | 0 tdm-be/src/swagger/swagger.js | 50 ++++++++++++++++++ tdm-be/{ => src/swagger}/swagger.json | 0 tdm-be/swagger.js | 53 -------------------- tdm-be/tsconfig.json | 4 +- tdm-fe/package.json | 2 +- 8 files changed, 56 insertions(+), 57 deletions(-) rename tdm-be/{ => src/swagger}/swagger-config.json (100%) create mode 100644 tdm-be/src/swagger/swagger.js rename tdm-be/{ => src/swagger}/swagger.json (100%) delete mode 100644 tdm-be/swagger.js diff --git a/tdm-be/package.json b/tdm-be/package.json index 3eea5f6..6070f18 100644 --- a/tdm-be/package.json +++ b/tdm-be/package.json @@ -12,7 +12,7 @@ "start": "node app.js", "build": "tsc", "test": "echo \"Error: no test specified\" && exit 1", - "swagger-autogen": "node swagger.js 3000" + "swagger-autogen": "node src/swagger/swagger.js 3000" }, "keywords": [], "author": "", diff --git a/tdm-be/src/app.ts b/tdm-be/src/app.ts index 90c00d1..23e9cda 100644 --- a/tdm-be/src/app.ts +++ b/tdm-be/src/app.ts @@ -9,7 +9,7 @@ const dataEnrichmentRoute = require('./controller/data-enrichment'); const dataWrapperRoute = require('./controller/data-wrapper'); const traitmentRoute = require('./controller/traitment'); const webhookRoute = require('./controller/webhook'); -const swaggerFile = require('../swagger-config.json'); +const swaggerFile = require('./swagger/swagger-config.json'); const cors = require('cors'); const basicAuth = require('express-basic-auth'); // This package is used for basic authentication const cron = require('node-cron'); diff --git a/tdm-be/swagger-config.json b/tdm-be/src/swagger/swagger-config.json similarity index 100% rename from tdm-be/swagger-config.json rename to tdm-be/src/swagger/swagger-config.json diff --git a/tdm-be/src/swagger/swagger.js b/tdm-be/src/swagger/swagger.js new file mode 100644 index 0000000..f12bebd --- /dev/null +++ b/tdm-be/src/swagger/swagger.js @@ -0,0 +1,50 @@ +const swaggerJsdoc = require('swagger-jsdoc'); +const fs = require('fs'); + +const swaggerOptions = { + definition: { + openapi: '3.0.0', + info: { + title: 'Express Swagger API', + version: '1.0.0', + description: 'A simple Express API with Swagger documentation', + }, + servers: [ + { + url: `/api`, + }, + ], + }, + apis: ['./routers/data-enrichment.ts', './routers/data-wrapper.ts', './routers/traitment.ts'], // Specify the file containing your routes +}; + +const swaggerOptionsConfig = { + definition: { + openapi: '3.0.0', + info: { + title: 'Express Swagger API', + version: '1.0.0', + description: 'A simple Express API with Swagger documentation', + }, + servers: [ + { + url: `/`, + }, + ], + }, + apis: ['./routers/config.ts'], // Specify the file containing your routes +}; + +const swaggerSpec = swaggerJsdoc(swaggerOptions); + +// Write Swagger JSON to a file +const swaggerJson = JSON.stringify(swaggerSpec, null, 2); +fs.writeFileSync('swagger.json', swaggerJson); + +const swaggerSpecConfig = swaggerJsdoc(swaggerOptionsConfig); + +// Write Swagger JSON to a file +const swaggerJsonConfig = JSON.stringify(swaggerSpecConfig, null, 2); +fs.writeFileSync('swagger-config.json', swaggerJsonConfig); + +console.log('Swagger JSON file generated successfully'); diff --git a/tdm-be/swagger.json b/tdm-be/src/swagger/swagger.json similarity index 100% rename from tdm-be/swagger.json rename to tdm-be/src/swagger/swagger.json diff --git a/tdm-be/swagger.js b/tdm-be/swagger.js deleted file mode 100644 index 1df358d..0000000 --- a/tdm-be/swagger.js +++ /dev/null @@ -1,53 +0,0 @@ -const swaggerJsdoc = require('swagger-jsdoc'); -const fs = require('fs'); - -const swaggerOptions = { - definition: { - openapi: '3.0.0', - info: { - title: 'Express Swagger API', - version: '1.0.0', - description: 'A simple Express API with Swagger documentation', - }, - servers : [{ - url: `/api`, - }], - }, - apis: [ - './routers/data-enrichment.ts', - './routers/data-wrapper.ts', - './routers/traitment.ts', - ], // Specify the file containing your routes - }; - - -const swaggerOptionsConfig = { - definition: { - openapi: '3.0.0', - info: { - title: 'Express Swagger API', - version: '1.0.0', - description: 'A simple Express API with Swagger documentation', - }, - servers : [{ - url: `/`, - }], - }, - apis: [ - './routers/config.ts' - ], // Specify the file containing your routes -}; - -const swaggerSpec = swaggerJsdoc(swaggerOptions); - -// Write Swagger JSON to a file -const swaggerJson = JSON.stringify(swaggerSpec, null, 2); -fs.writeFileSync('swagger.json', swaggerJson); - -const swaggerSpecConfig = swaggerJsdoc(swaggerOptionsConfig); - -// Write Swagger JSON to a file -const swaggerJsonConfig = JSON.stringify(swaggerSpecConfig, null, 2); -fs.writeFileSync('swagger-config.json', swaggerJsonConfig); - -console.log('Swagger JSON file generated successfully'); \ No newline at end of file diff --git a/tdm-be/tsconfig.json b/tdm-be/tsconfig.json index 9875f54..858e8fe 100644 --- a/tdm-be/tsconfig.json +++ b/tdm-be/tsconfig.json @@ -11,10 +11,12 @@ "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "allowJs": true }, "include": [ "src/**/*.ts", + "src/**/*.js", "config/config.json" ], "exclude": [ diff --git a/tdm-fe/package.json b/tdm-fe/package.json index 8ef0e91..6cb18c6 100644 --- a/tdm-fe/package.json +++ b/tdm-fe/package.json @@ -6,7 +6,7 @@ "dev": "next dev", "build": "next build", "start": "next start -p 8080", - "generate-api": "openapi-generator-cli generate -i ../tdm-be/swagger.json -g typescript-axios -o src/generated", + "generate-api": "openapi-generator-cli generate -i ../tdm-be/src/swagger/swagger.json -g typescript-axios -o src/generated", "lint": "next lint" }, "dependencies": { From 595bc68bde922c1d99026d1e365e1b8cb7073eed Mon Sep 17 00:00:00 2001 From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:02:19 +0100 Subject: [PATCH 6/8] build: fix swagger --- Dockerfile | 2 -- tdm-be/src/app.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index a9cbe43..263fade 100644 --- a/Dockerfile +++ b/Dockerfile @@ -74,8 +74,6 @@ WORKDIR /app COPY --chown=daemon:daemon --from=express-build /app/package.json /app/ COPY --chown=daemon:daemon --from=express-build /app/package-lock.json /app/ COPY --chown=daemon:daemon --from=node-modules /app/node_modules /app/node_modules/ -COPY --chown=daemon:daemon --from=express-build /app/swagger-config.json /app/ -COPY --chown=daemon:daemon --from=express-build /app/swagger.json /app/ COPY --chown=daemon:daemon --from=express-build /app/config/default.json /app/config/ COPY --chown=daemon:daemon --from=express-build /app/dist /app/ diff --git a/tdm-be/src/app.ts b/tdm-be/src/app.ts index 23e9cda..c309612 100644 --- a/tdm-be/src/app.ts +++ b/tdm-be/src/app.ts @@ -1,5 +1,6 @@ import environment from './lib/config'; import logger, { httpLogger, cronLogger } from './lib/logger'; +import swaggerFile from './swagger/swagger-config.json'; import express from 'express'; import fs from 'node:fs'; @@ -9,7 +10,6 @@ const dataEnrichmentRoute = require('./controller/data-enrichment'); const dataWrapperRoute = require('./controller/data-wrapper'); const traitmentRoute = require('./controller/traitment'); const webhookRoute = require('./controller/webhook'); -const swaggerFile = require('./swagger/swagger-config.json'); const cors = require('cors'); const basicAuth = require('express-basic-auth'); // This package is used for basic authentication const cron = require('node-cron'); From 94be36f055ab99401473784d773887883620fbcb Mon Sep 17 00:00:00 2001 From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com> Date: Fri, 9 Feb 2024 15:11:27 +0100 Subject: [PATCH 7/8] fix: update http log message to show url --- tdm-be/src/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tdm-be/src/app.ts b/tdm-be/src/app.ts index c309612..c35cc07 100644 --- a/tdm-be/src/app.ts +++ b/tdm-be/src/app.ts @@ -35,7 +35,7 @@ const auth = basicAuth({ }); app.use((req, res, next) => { - httpLogger.info(`${req.method} ${req.baseUrl} - ${req.ip}/${req.get('user-agent')}`); + httpLogger.info(`${req.method} ${req.url} - ${req.ip} - ${req.get('user-agent')}`); next(); }); From 5a2403d9d462e026666a9fec50d3a42a682a612c Mon Sep 17 00:00:00 2001 From: AlasDiablo <25723276+AlasDiablo@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:31:45 +0100 Subject: [PATCH 8/8] fix: remove mention of removed file --- tdm-be/tsconfig.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tdm-be/tsconfig.json b/tdm-be/tsconfig.json index 858e8fe..4461f80 100644 --- a/tdm-be/tsconfig.json +++ b/tdm-be/tsconfig.json @@ -16,8 +16,7 @@ }, "include": [ "src/**/*.ts", - "src/**/*.js", - "config/config.json" + "src/**/*.js" ], "exclude": [ "node_modules",