From 11856846d87ae4314a943e139cf638e8921e594e Mon Sep 17 00:00:00 2001 From: Dinawo Date: Wed, 8 May 2024 01:12:12 +0200 Subject: [PATCH] Refactor Dockerfile and docker-compose.yml to use new directory structure and update volume paths --- Dockerfile | 2 +- ...discordWebhookSuspisiousAlertMiddleware.js | 55 ++ controllers/paramController.js | 28 - docker-compose.yml | 10 +- models/AuthUser.js | 29 - models/paramModel.js | 16 - models/reportManager.js | 2 +- models/swagger.js | 30 + models/updateHelper.js | 20 - models/updateManager.js | 141 ---- package-lock.json | 619 ++++++++++++++---- package.json | 4 +- public/js/dashboard.js | 81 ++- routes/Dpanel/API/GetMetaDataFile.js | 53 ++ routes/Dpanel/API/MoveFile.js | 14 +- routes/Dpanel/API/Update-Setup-Admin.js | 33 +- routes/Dpanel/Admin/SettingSetup.js | 9 +- routes/index.js | 55 -- routes/routes.js | 25 +- views/dashboard.ejs | 24 +- views/paramAdminSettingSetup.ejs | 6 +- 21 files changed, 781 insertions(+), 475 deletions(-) create mode 100644 Middlewares/discordWebhookSuspisiousAlertMiddleware.js delete mode 100644 controllers/paramController.js delete mode 100644 models/AuthUser.js delete mode 100644 models/paramModel.js create mode 100644 models/swagger.js delete mode 100644 models/updateHelper.js delete mode 100644 models/updateManager.js create mode 100644 routes/Dpanel/API/GetMetaDataFile.js diff --git a/Dockerfile b/Dockerfile index 6d63d64..86feb8c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:14 +FROM node:20 WORKDIR /srv/docker/cdn-app-insider diff --git a/Middlewares/discordWebhookSuspisiousAlertMiddleware.js b/Middlewares/discordWebhookSuspisiousAlertMiddleware.js new file mode 100644 index 0000000..f53f9c7 --- /dev/null +++ b/Middlewares/discordWebhookSuspisiousAlertMiddleware.js @@ -0,0 +1,55 @@ +const axios = require('axios'); +const fs = require('fs'); +const path = require('path'); +const setupFilePath = path.join(__dirname, '../data', 'setup.json'); +const setupData = JSON.parse(fs.readFileSync(setupFilePath, 'utf-8')); + +function sendDiscordWebhook(url, req, statusCode) { + const fullUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`; + + const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; + + const statusEmoji = statusCode === 200 ? '✅' : '❌'; + const statusMessage = `**Statut:** ${statusEmoji} (${statusCode})`; + + const timestamp = new Date().toLocaleString('fr-FR', { timeZone: 'UTC', hour12: false }); + const userAgent = req.get('User-Agent'); + + const { v4: uuidv4 } = require('uuid'); + + const webhookId = uuidv4(); + + const userId = req.user ? req.user.id : 'Inconnu'; + const userName = req.user ? req.user.name : 'Inconnu'; + + const data = { + embeds: [{ + title: "📡 Requête API", + description: "Une requête API a été effectuée. Voici les détails :", + color: 16753920, + fields: [{ + name: `🔎 Détails de la requête\n\n`, + value: `🔗 **URL:** ${fullUrl}\n\n🚦 ${statusMessage}\n\n🌐 **IP**: ${ip}\n\n🔧 **Méthode**: ${req.method}\n\n⏰ **Heure**: ${timestamp}\n\n🕵️ **Agent utilisateur**: ${userAgent}\n\n👤 **Utilisateur**: ${userName} (*ID: ${userId}*)`, + inline: false + }], + footer: { + text: `📚 Journal des requêtes API | ${webhookId}` + } + }] + }; + + axios.post(url, data) + .catch((error) => { + console.error(`Erreur lors de l'envoi du webhook à Discord: ${error}`); + }); +} + +function discordWebhookSuspisiousAlertMiddleware(req, res, next) { + res.on('finish', () => { + const discordWebhookUrl = setupData[0].webhooks_discord; + sendDiscordWebhook(discordWebhookUrl, req, res.statusCode); + }); + next(); +} + +module.exports = discordWebhookSuspisiousAlertMiddleware; \ No newline at end of file diff --git a/controllers/paramController.js b/controllers/paramController.js deleted file mode 100644 index 0a7874f..0000000 --- a/controllers/paramController.js +++ /dev/null @@ -1,28 +0,0 @@ -const mysql = require('mysql2/promise'); -const pool = require('../config/database'); - -async function getParams() { - const connection = await pool.getConnection(); - try { - const [rows] = await connection.execute('SELECT * FROM cdn'); - return { - users: rows[0].users, - }; - } finally { - connection.release(); - } -} - -async function updateParams(params) { - const connection = await pool.getConnection(); - try { - await connection.execute('UPDATE cdn SET ?', [params]); - } finally { - connection.release(); - } -} - -module.exports = { - getParams, - updateParams -}; diff --git a/docker-compose.yml b/docker-compose.yml index 2a73ec3..a591e50 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,7 @@ version: '3' services: - app: + cdn-app-insider: + container_name: cdn-app-insider image: swiftlogiclabs/cdn-app-insider ports: - 5053:5053 @@ -8,4 +9,9 @@ services: - /srv/docker/cdn-app-insider/data:/data - /srv/docker/cdn-app-insider/report:/report - /srv/docker/cdn-app-insider/cdn-files:/cdn-files - restart: unless-stopped \ No newline at end of file + networks: + - cdn_app_insider_network + restart: unless-stopped + +networks: + cdn_app_insider_network: \ No newline at end of file diff --git a/models/AuthUser.js b/models/AuthUser.js deleted file mode 100644 index 254cf48..0000000 --- a/models/AuthUser.js +++ /dev/null @@ -1,29 +0,0 @@ -const pgp = require('pg-promise') -const pool = require('../config/database'); -const bcrypt = require('bcrypt'); - -async function registerUser(username, password) { - const hashedPassword = await bcrypt.hash(password, 10); - const connection = await pool.getConnection(); - try { - const [rows] = await connection.execute('INSERT INTO cdn (username, password) VALUES (?, ?)', [username, hashedPassword]); - return rows.insertId; - } finally { - connection.release(); - } -} - - async function getUserByUsername(username) { - const connection = await pool.getConnection(); - try { - const [rows] = await connection.execute('SELECT * FROM cdn WHERE username = ?', [username]); - return rows[0]; - } finally { - connection.release(); - } - } - - module.exports = { - registerUser, - getUserByUsername, - }; \ No newline at end of file diff --git a/models/paramModel.js b/models/paramModel.js deleted file mode 100644 index 31ca6e2..0000000 --- a/models/paramModel.js +++ /dev/null @@ -1,16 +0,0 @@ -const mysql = require('mysql2/promise'); -const pool = require('../config/database'); - -async function getUsers() { - const connection = await pool.getConnection(); - try { - const [rows] = await connection.execute('SELECT * FROM cdn'); - return rows || []; - } finally { - connection.release(); - } -} - -module.exports = { - getUsers -}; diff --git a/models/reportManager.js b/models/reportManager.js index 3f1f83a..ce60b99 100644 --- a/models/reportManager.js +++ b/models/reportManager.js @@ -74,7 +74,7 @@ class SystemReport { try { - const response = await fetch('https://apollon.dinawo.fr/api/report/receive', { + const response = await fetch('https://cdn-apollon-p198-61m1.dinawo.fr/api/report/receive', { method: 'POST', headers: { 'Content-Type': 'application/json' diff --git a/models/swagger.js b/models/swagger.js new file mode 100644 index 0000000..0ccd002 --- /dev/null +++ b/models/swagger.js @@ -0,0 +1,30 @@ +const swaggerJsDoc = require('swagger-jsdoc'); +const swaggerUi = require('swagger-ui-express'); + +const swaggerOptions = { + swaggerDefinition: { + info: { + title: 'API - ManageMate', + version: '1.0-beta.1', + description: 'This documentation describes the ManageMate API.', + }, + servers: [{ url: 'http://localhost:' + (process.env.PORT || 35665) }], + basePath: '/api/v1/', + }, + apis: ['./routes/Dpanel/Api/*.js'], +}; + +const swaggerDocs = swaggerJsDoc(swaggerOptions); + +const customCss = ` + .swagger-ui .topbar .link { + display: none; + } +`; + +module.exports = { + serve: swaggerUi.serve, + setup: swaggerUi.setup(swaggerDocs, { + customCss + }), +}; \ No newline at end of file diff --git a/models/updateHelper.js b/models/updateHelper.js deleted file mode 100644 index d8436f5..0000000 --- a/models/updateHelper.js +++ /dev/null @@ -1,20 +0,0 @@ -const fs = require('fs'); -const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); -const AdmZip = require('adm-zip'); -const { logger, ErrorLogger, logRequestInfo } = require('../config/logs'); - -function compareAndUpdate(currentPath, updatedPath) { -} - -async function downloadUpdate(updateUrl, destinationPath) { - const response = await fetch(updateUrl); - const buffer = await response.buffer(); - fs.writeFileSync(destinationPath, buffer); -} - -function unzipUpdate(zipPath, extractionPath) { - const zip = new AdmZip(zipPath); - zip.extractAllTo(extractionPath, /*overwrite*/ true); -} - -module.exports = { compareAndUpdate, downloadUpdate, unzipUpdate }; diff --git a/models/updateManager.js b/models/updateManager.js deleted file mode 100644 index 8502240..0000000 --- a/models/updateManager.js +++ /dev/null @@ -1,141 +0,0 @@ -const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); -const fs = require('fs').promises; -const path = require('path'); -const AdmZip = require('adm-zip'); -const util = require('util'); -const ncp = util.promisify(require('ncp').ncp); -const { downloadUpdate, unzipUpdate } = require('../models/updateHelper'); -const { logger, ErrorLogger } = require('../config/logs'); - -async function getFilesInVersion() { - try { - const response = await fetch('https://apollon.dinawo.fr/api/get/version'); - const data = await response.json(); - return data.update.files || []; - } catch (error) { - throw new Error(`Error getting files in version: ${error.message}`); - } -} - -async function listFilesInZip(zipFilePath) { - try { - const zip = new AdmZip(zipFilePath); - const zipEntries = zip.getEntries(); - return zipEntries.map(entry => entry.entryName); - } catch (error) { - throw new Error(`Error listing files in zip: ${error.message}`); - } -} - -async function deleteFileOrDirectory(filePath) { - try { - const stats = await fs.stat(filePath); - if (stats.isDirectory()) { - logger.info(`Skipped deletion of directory: ${filePath}`); - } else { - await fs.unlink(filePath); - logger.info(`Updated file deleted: ${filePath}`); - } - } catch (error) { - throw new Error(`Error deleting updated file or directory ${filePath}: ${error.message}`); - } -} - -ncp.limit = 16; - -async function moveFilesFromTemp(basePath, tempExtractFolder, filesInZip) { - const entries = await fs.readdir(tempExtractFolder, { withFileTypes: true }); - - for (const entry of entries) { - const sourcePath = path.join(tempExtractFolder, entry.name); - const targetPath = path.join(basePath, entry.name); - - if (entry.isDirectory()) { - await fs.mkdir(targetPath, { recursive: true }); - await ncp(sourcePath, targetPath); - } else { - const relativePath = path.relative(tempExtractFolder, sourcePath); - - logger.info(`Processing file: ${relativePath}`); - - if (filesInZip.includes(relativePath)) { - const destinationPath = path.join(basePath, relativePath); - await fs.mkdir(path.dirname(destinationPath), { recursive: true }); - - try { - await fs.rename(sourcePath, destinationPath); - logger.info(`File moved: ${relativePath}`); - } catch (moveError) { - logger.error(`Error moving file: ${relativePath}`, moveError); - } - } else { - logger.info(`Skipped moving file: ${relativePath}`); - } - } - } -} - -async function applyUpdate(updateUrl, updateFolder) { - const updateFilePath = path.join(updateFolder, 'update.zip'); - - try { - await downloadUpdate(updateUrl, updateFilePath); - - const filesInZip = await listFilesInZip(updateFilePath); - logger.info('Zip contents:', filesInZip); - - const filesInVersion = await getFilesInVersion(); - logger.info('Content of current version:', filesInVersion); - - for (const file of filesInVersion) { - try { - await deleteFileOrDirectory(path.join(updateFolder, file)); - } catch (error) { - ErrorLogger.error(`Error deleting updated file or directory ${file}: ${error.message}`); - } - } - - const tempExtractFolder = path.join(updateFolder, 'temp_extract'); - await unzipUpdate(updateFilePath, tempExtractFolder); - - await moveFilesFromTemp(updateFolder, tempExtractFolder, filesInZip); - - logger.info('Update successful. The update has been applied successfully.'); - - } catch (error) { - ErrorLogger.error(`Error applying update: ${error.message}`); - } finally { - await cleanUp(updateFolder, updateFilePath); - } -} - -async function cleanUp(basePath, zipFilePath) { - const tempExtractFolder = path.join(basePath, 'temp_extract'); - await fs.rm(tempExtractFolder, { recursive: true }); - - await fs.unlink(zipFilePath); - logger.info('Temporary files successfully deleted.'); -} - -async function checkForUpdates() { - try { - logger.info('Checking for updates...'); - const response = await fetch('https://apollon.dinawo.fr/api/checkupdate'); - const result = await response.json(); - - if (result.updateAvailable) { - const updateUrl = 'https://apollon.dinawo.fr/api/download/all'; - const updateFolder = path.join(__dirname, '..'); - - await fs.mkdir(updateFolder, { recursive: true }); - - await applyUpdate(updateUrl, updateFolder); - } else { - logger.info('No updates available.'); - } - } catch (error) { - logger.error('Error checking for updates:', error.message); - } -} - -module.exports = { applyUpdate, listFilesInZip, checkForUpdates }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 127b743..b131b5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cdn-app/insider-swiftlogic-labs-dinawo", - "version": "1.0.0-beta.10", + "version": "1.0.0-beta.11", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@cdn-app/insider-swiftlogic-labs-dinawo", - "version": "1.0.0-beta.10", + "version": "1.0.0-beta.11", "license": "ISC", "dependencies": { "@auth/express": "^0.5.1", @@ -50,6 +50,8 @@ "semver": "^7.5.4", "slugify": "^1.6.6", "socket.io": "^4.7.2", + "swagger-jsdoc": "^6.2.8", + "swagger-ui-express": "^5.0.0", "sweetalert2": "^11.10.0", "systeminformation": "^5.22.0", "tailwindcss": "^3.3.5", @@ -73,10 +75,50 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz", + "integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, + "node_modules/@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" + }, + "node_modules/@apidevtools/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^9.0.6", + "@apidevtools/openapi-schemas": "^2.0.4", + "@apidevtools/swagger-methods": "^3.0.2", + "@jsdevtools/ono": "^7.1.3", + "call-me-maybe": "^1.0.1", + "z-schema": "^5.0.1" + }, + "peerDependencies": { + "openapi-types": ">=7" + } + }, "node_modules/@auth/core": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.29.0.tgz", - "integrity": "sha512-MdfEjU6WRjUnPG1+XeBWrTIlAsLZU6V0imCIqVDDDPxLI6UZWldXVqAA2EsDazGofV78jqiCLHaN85mJITDqdg==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.30.0.tgz", + "integrity": "sha512-8AE4m/nk+4EIiVCJwxZAsJeAQuzpEC8M8768mmKVn60CGDdupKQkVhxbRlm5Qh7eNRCoFFME+0DvtaX2aXrYaA==", "dependencies": { "@panva/hkdf": "^1.1.1", "@types/cookie": "0.6.0", @@ -104,11 +146,11 @@ } }, "node_modules/@auth/express": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@auth/express/-/express-0.5.2.tgz", - "integrity": "sha512-Z2t56JGhBrn2pHPjFGbqx+atXBKWx24OhlbBZiYBOw29d52OaBc6Ewyh1AQJ8sLWD6peiX3GrLV436qvtI1Stg==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@auth/express/-/express-0.5.4.tgz", + "integrity": "sha512-8mULCeTQ5IhVKMWtfvgIxt7y92yh2j0KFolJ60sCtEHxM75MoWRs7GXBEg/QyxQcIeZyxcpfKPH7xcAeJwDh0Q==", "dependencies": { - "@auth/core": "0.29.0" + "@auth/core": "0.30.0" }, "peerDependencies": { "express": "^4.18.2" @@ -237,6 +279,11 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", @@ -322,9 +369,9 @@ } }, "node_modules/@socket.io/component-emitter": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.1.tgz", - "integrity": "sha512-dzJtaDAAoXx4GCOJpbB2eG/Qj8VDpdwkLsWGzGm+0L7E8/434RyMbAHmk9ubXWVAb9nXmc44jUf8GKqVDiKezg==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", @@ -355,10 +402,15 @@ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, "node_modules/@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "version": "20.12.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.10.tgz", + "integrity": "sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==", "dependencies": { "undici-types": "~5.26.4" } @@ -633,6 +685,11 @@ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -936,6 +993,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" + }, "node_modules/camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", @@ -1060,9 +1122,9 @@ } }, "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", "engines": { "node": ">= 6" } @@ -1212,9 +1274,9 @@ } }, "node_modules/daisyui": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.10.1.tgz", - "integrity": "sha512-Ds0Z0Fv+Xf6ZEqV4Q5JIOeKfg83xxnww0Lzid0V94vPtlQ0yYmucEa33zSctsX2VEgBALtmk5zVEqd59pnUbuQ==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.11.1.tgz", + "integrity": "sha512-obT9CUbQdW6eoHwSeT5VwaRrWlwrM4OT5qlfdJ0oQlSIEYhwnEl2+L2fwu5PioLbitwuMdYC2X8I1cyy8Pf6LQ==", "dev": true, "dependencies": { "css-selector-tokenizer": "^0.8", @@ -1392,6 +1454,17 @@ "node": ">=6" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -1542,6 +1615,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -2388,9 +2469,9 @@ } }, "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -2484,6 +2565,17 @@ "url": "https://github.com/sponsors/panva" } }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -2555,6 +2647,21 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, "node_modules/lodash.orderby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.orderby/-/lodash.orderby-4.6.0.tgz", @@ -2849,9 +2956,9 @@ } }, "node_modules/mysql2": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.4.tgz", - "integrity": "sha512-OEESQuwxMza803knC1YSt7NMuc1BrK9j7gZhCSs2WAyxr1vfiI7QLaLOKTh5c9SWGz98qVyQUbK8/WckevNQhg==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.7.tgz", + "integrity": "sha512-KnJT8vYRcNAZv73uf9zpXqNbvBG7DJrs+1nACsjZP1HMJ1TgXEy8wnNilXAn/5i57JizXKtrUtwDB7HxT9DDpw==", "dependencies": { "denque": "^2.1.0", "generate-function": "^2.3.1", @@ -3141,6 +3248,12 @@ "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", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "peer": true + }, "node_modules/os-utils": { "version": "0.0.14", "resolved": "https://registry.npmjs.org/os-utils/-/os-utils-0.0.14.tgz", @@ -3304,9 +3417,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "engines": { "node": "14 || >=16.14" } @@ -3562,6 +3675,17 @@ "url": "https://github.com/sponsors/antonk52" } }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", + "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/postcss-nested": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", @@ -3949,12 +4073,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", + "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", "bin": { "semver": "bin/semver.js" }, @@ -3962,17 +4083,6 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -4314,6 +4424,14 @@ "balanced-match": "^1.0.0" } }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/sucrase/node_modules/glob": { "version": "10.3.12", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", @@ -4350,9 +4468,9 @@ } }, "node_modules/sucrase/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "engines": { "node": ">=16 || 14 >=14.17" } @@ -4380,19 +4498,87 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-jsdoc": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz", + "integrity": "sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==", + "dependencies": { + "commander": "6.2.0", + "doctrine": "3.0.0", + "glob": "7.1.6", + "lodash.mergewith": "^4.6.2", + "swagger-parser": "^10.0.3", + "yaml": "2.0.0-1" + }, + "bin": { + "swagger-jsdoc": "bin/swagger-jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==", + "dependencies": { + "@apidevtools/swagger-parser": "10.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/swagger-ui-dist": { + "version": "5.17.6", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.6.tgz", + "integrity": "sha512-8P48+WvFKDF7YoDqmWq3EItwdOh7tJlPSZ7y6CNqQIPMQ+qZVI0iNlBMSzyU+PXOd1M8ndRiNKWOvfItREBvHg==" + }, + "node_modules/swagger-ui-express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.0.tgz", + "integrity": "sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA==", + "dependencies": { + "swagger-ui-dist": ">=5.0.0" + }, + "engines": { + "node": ">= v0.10.32" + }, + "peerDependencies": { + "express": ">=4.0.0 || >=5.0.0-beta" + } + }, "node_modules/sweetalert2": { - "version": "11.10.7", - "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.7.tgz", - "integrity": "sha512-5Jlzrmaitay6KzU+2+LhYu9q+L4v/dZ8oZyEDH14ep0C/QilCnFLHmqAyD/Lhq/lm5DiwsOs6Tr58iv8k3wyGg==", + "version": "11.10.8", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.8.tgz", + "integrity": "sha512-oAkYROBfXBY+4sVbQEIcN+ZxAx69lsmz5WEBwdEpyS4m59vOBNlRU5/fJpAI1MVfiDwFZiGwVzB/KBpOyfLNtg==", "funding": { "type": "individual", "url": "https://github.com/sponsors/limonte" } }, "node_modules/systeminformation": { - "version": "5.22.7", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.7.tgz", - "integrity": "sha512-AWxlP05KeHbpGdgvZkcudJpsmChc2Y5Eo/GvxG/iUA/Aws5LZKHAMSeAo+V+nD+nxWZaxrwpWcnx4SH3oxNL3A==", + "version": "5.22.8", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.8.tgz", + "integrity": "sha512-F1iWQ+PSfOzvLMGh2UXASaWLDq5o+1h1db13Kddl6ojcQ47rsJhpMtRrmBXfTA5QJgutC4KV67YRmXLuroIxrA==", "os": [ "darwin", "linux", @@ -4680,6 +4866,14 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -5015,14 +5209,39 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "version": "2.0.0-1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz", + "integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "dependencies": { + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + }, "bin": { - "yaml": "bin.mjs" + "z-schema": "bin/z-schema" }, "engines": { - "node": ">= 14" + "node": ">=8.0.0" + }, + "optionalDependencies": { + "commander": "^9.4.1" + } + }, + "node_modules/z-schema/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "optional": true, + "engines": { + "node": "^12.20.0 || >=14" } } }, @@ -5032,10 +5251,44 @@ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==" }, + "@apidevtools/json-schema-ref-parser": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz", + "integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==", + "requires": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, + "@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==" + }, + "@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" + }, + "@apidevtools/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==", + "requires": { + "@apidevtools/json-schema-ref-parser": "^9.0.6", + "@apidevtools/openapi-schemas": "^2.0.4", + "@apidevtools/swagger-methods": "^3.0.2", + "@jsdevtools/ono": "^7.1.3", + "call-me-maybe": "^1.0.1", + "z-schema": "^5.0.1" + } + }, "@auth/core": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.29.0.tgz", - "integrity": "sha512-MdfEjU6WRjUnPG1+XeBWrTIlAsLZU6V0imCIqVDDDPxLI6UZWldXVqAA2EsDazGofV78jqiCLHaN85mJITDqdg==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@auth/core/-/core-0.30.0.tgz", + "integrity": "sha512-8AE4m/nk+4EIiVCJwxZAsJeAQuzpEC8M8768mmKVn60CGDdupKQkVhxbRlm5Qh7eNRCoFFME+0DvtaX2aXrYaA==", "requires": { "@panva/hkdf": "^1.1.1", "@types/cookie": "0.6.0", @@ -5047,11 +5300,11 @@ } }, "@auth/express": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@auth/express/-/express-0.5.2.tgz", - "integrity": "sha512-Z2t56JGhBrn2pHPjFGbqx+atXBKWx24OhlbBZiYBOw29d52OaBc6Ewyh1AQJ8sLWD6peiX3GrLV436qvtI1Stg==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@auth/express/-/express-0.5.4.tgz", + "integrity": "sha512-8mULCeTQ5IhVKMWtfvgIxt7y92yh2j0KFolJ60sCtEHxM75MoWRs7GXBEg/QyxQcIeZyxcpfKPH7xcAeJwDh0Q==", "requires": { - "@auth/core": "0.29.0" + "@auth/core": "0.30.0" } }, "@colors/colors": { @@ -5146,6 +5399,11 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" + }, "@leichtgewicht/ip-codec": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", @@ -5207,9 +5465,9 @@ "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==" }, "@socket.io/component-emitter": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.1.tgz", - "integrity": "sha512-dzJtaDAAoXx4GCOJpbB2eG/Qj8VDpdwkLsWGzGm+0L7E8/434RyMbAHmk9ubXWVAb9nXmc44jUf8GKqVDiKezg==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" }, "@szmarczak/http-timer": { "version": "5.0.1", @@ -5237,10 +5495,15 @@ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, "@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "version": "20.12.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.10.tgz", + "integrity": "sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==", "requires": { "undici-types": "~5.26.4" } @@ -5454,6 +5717,11 @@ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -5690,6 +5958,11 @@ "set-function-length": "^1.2.1" } }, + "call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" + }, "camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", @@ -5782,9 +6055,9 @@ } }, "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==" }, "concat-map": { "version": "0.0.1", @@ -5897,9 +6170,9 @@ "dev": true }, "daisyui": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.10.1.tgz", - "integrity": "sha512-Ds0Z0Fv+Xf6ZEqV4Q5JIOeKfg83xxnww0Lzid0V94vPtlQ0yYmucEa33zSctsX2VEgBALtmk5zVEqd59pnUbuQ==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.11.1.tgz", + "integrity": "sha512-obT9CUbQdW6eoHwSeT5VwaRrWlwrM4OT5qlfdJ0oQlSIEYhwnEl2+L2fwu5PioLbitwuMdYC2X8I1cyy8Pf6LQ==", "dev": true, "requires": { "css-selector-tokenizer": "^0.8", @@ -6015,6 +6288,14 @@ "dns-packet": "^5.2.4" } }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, "dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", @@ -6124,6 +6405,11 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -6765,9 +7051,9 @@ } }, "jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "requires": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -6830,6 +7116,14 @@ "resolved": "https://registry.npmjs.org/jose/-/jose-5.2.4.tgz", "integrity": "sha512-6ScbIk2WWCeXkmzF6bRPmEuaqy1m8SbsRFMa/FLrSCkGIhj8OLVG/IH+XHVmNMx/KUo8cVWEE6oKR4dJ+S0Rkg==" }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -6890,6 +7184,21 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, "lodash.orderby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.orderby/-/lodash.orderby-4.6.0.tgz", @@ -7103,9 +7412,9 @@ } }, "mysql2": { - "version": "3.9.4", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.4.tgz", - "integrity": "sha512-OEESQuwxMza803knC1YSt7NMuc1BrK9j7gZhCSs2WAyxr1vfiI7QLaLOKTh5c9SWGz98qVyQUbK8/WckevNQhg==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.7.tgz", + "integrity": "sha512-KnJT8vYRcNAZv73uf9zpXqNbvBG7DJrs+1nACsjZP1HMJ1TgXEy8wnNilXAn/5i57JizXKtrUtwDB7HxT9DDpw==", "requires": { "denque": "^2.1.0", "generate-function": "^2.3.1", @@ -7305,6 +7614,12 @@ "fn.name": "1.x.x" } }, + "openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "peer": true + }, "os-utils": { "version": "0.0.14", "resolved": "https://registry.npmjs.org/os-utils/-/os-utils-0.0.14.tgz", @@ -7425,9 +7740,9 @@ }, "dependencies": { "lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==" + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==" } } }, @@ -7578,6 +7893,11 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==" + }, + "yaml": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", + "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==" } } }, @@ -7832,22 +8152,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - } - } + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", + "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==" }, "send": { "version": "0.18.0", @@ -8121,6 +8428,11 @@ "balanced-match": "^1.0.0" } }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + }, "glob": { "version": "10.3.12", "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", @@ -8142,9 +8454,9 @@ } }, "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==" } } }, @@ -8162,15 +8474,64 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "swagger-jsdoc": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz", + "integrity": "sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==", + "requires": { + "commander": "6.2.0", + "doctrine": "3.0.0", + "glob": "7.1.6", + "lodash.mergewith": "^4.6.2", + "swagger-parser": "^10.0.3", + "yaml": "2.0.0-1" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==", + "requires": { + "@apidevtools/swagger-parser": "10.0.3" + } + }, + "swagger-ui-dist": { + "version": "5.17.6", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.6.tgz", + "integrity": "sha512-8P48+WvFKDF7YoDqmWq3EItwdOh7tJlPSZ7y6CNqQIPMQ+qZVI0iNlBMSzyU+PXOd1M8ndRiNKWOvfItREBvHg==" + }, + "swagger-ui-express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.0.tgz", + "integrity": "sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA==", + "requires": { + "swagger-ui-dist": ">=5.0.0" + } + }, "sweetalert2": { - "version": "11.10.7", - "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.7.tgz", - "integrity": "sha512-5Jlzrmaitay6KzU+2+LhYu9q+L4v/dZ8oZyEDH14ep0C/QilCnFLHmqAyD/Lhq/lm5DiwsOs6Tr58iv8k3wyGg==" + "version": "11.10.8", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.8.tgz", + "integrity": "sha512-oAkYROBfXBY+4sVbQEIcN+ZxAx69lsmz5WEBwdEpyS4m59vOBNlRU5/fJpAI1MVfiDwFZiGwVzB/KBpOyfLNtg==" }, "systeminformation": { - "version": "5.22.7", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.7.tgz", - "integrity": "sha512-AWxlP05KeHbpGdgvZkcudJpsmChc2Y5Eo/GvxG/iUA/Aws5LZKHAMSeAo+V+nD+nxWZaxrwpWcnx4SH3oxNL3A==" + "version": "5.22.8", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.8.tgz", + "integrity": "sha512-F1iWQ+PSfOzvLMGh2UXASaWLDq5o+1h1db13Kddl6ojcQ47rsJhpMtRrmBXfTA5QJgutC4KV67YRmXLuroIxrA==" }, "tailwindcss": { "version": "3.4.3", @@ -8388,6 +8749,11 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -8635,9 +9001,28 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yaml": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", - "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==" + "version": "2.0.0-1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz", + "integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==" + }, + "z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "requires": { + "commander": "^9.4.1", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + }, + "dependencies": { + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "optional": true + } + } } } } diff --git a/package.json b/package.json index 7ed4b1b..9f8bb69 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cdn-app/insider-swiftlogic-labs-dinawo", - "version": "1.0.0-beta.10", + "version": "1.0.0-beta.11", "description": "", "main": "server.js", "scripts": { @@ -50,6 +50,8 @@ "semver": "^7.5.4", "slugify": "^1.6.6", "socket.io": "^4.7.2", + "swagger-jsdoc": "^6.2.8", + "swagger-ui-express": "^5.0.0", "sweetalert2": "^11.10.0", "systeminformation": "^5.22.0", "tailwindcss": "^3.3.5", diff --git a/public/js/dashboard.js b/public/js/dashboard.js index b196b91..024620c 100644 --- a/public/js/dashboard.js +++ b/public/js/dashboard.js @@ -203,6 +203,7 @@ }); } }; + function performUpdate() { fetch('/applyupdate') .then(response => response.json()) @@ -467,21 +468,71 @@ async function getUserIdFromFolder(username) { return user ? user.id : null; } -async function showFileInfo(fileLink) { +window.onload = async function() { + console.log("Page loaded, fetching file info..."); + let data; try { - let response = await fetch('/data/file_info.json'); + let response = await fetch('/api/dpanel/dashboard/getmetadatafile/file_info', { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + }); + console.log("Response from fetch:", response); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } - let fileContent = await response.text(); - data = JSON.parse(fileContent); + data = await response.json(); + console.log("Data from response:", data); } catch (error) { - console.log(error); + console.log("Error in fetch:", error); Swal.fire({ position: 'top', icon: 'error', title: 'Les informations sur le fichier ne sont pas disponibles pour le moment. Veuillez réessayer plus tard.', + text: `Error: ${error.message}`, + showConfirmButton: false, + timer: 1800, + toast: true, + }); + return; + } + + let table = document.getElementById("fileTable"); + for (let file of data) { + let row = table.insertRow(); + let cell = row.insertCell(); + cell.innerHTML = `${file.fileName}`; + } +} + +async function showFileInfo(fileLink) { + console.log("showFileInfo called with fileLink:", fileLink); + let data; + try { + let response = await fetch('/api/dpanel/dashboard/getmetadatafile/file_info', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + fileLink: fileLink, + }) + }); + console.log("Response from fetch:", response); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + data = await response.json(); + console.log("Data from response:", data); + } catch (error) { + console.log("Error in fetch:", error); + Swal.fire({ + position: 'top', + icon: 'error', + title: 'Les informations sur le fichier ne sont pas disponibles pour le moment. Veuillez réessayer plus tard.', + text: `Error: ${error.message}`, showConfirmButton: false, timer: 1800, toast: true, @@ -490,11 +541,12 @@ async function showFileInfo(fileLink) { } let pathParts = fileLink.split('/'); + console.log("pathParts:", pathParts); if (pathParts.length < 4) { Swal.fire({ position: 'top', icon: 'error', - title: `Le lien du fichier ${fileLink} n'est pas valide.`, + title: `The file link ${fileLink} is not valid.`, showConfirmButton: false, timer: 1800, toast: true, @@ -510,7 +562,7 @@ async function showFileInfo(fileLink) { Swal.fire({ position: 'top', icon: 'error', - title: `Aucune information trouvée pour le fichier ${fileName} pour l'utilisateur avec l'ID ${userId}.`, + title: `No information found for the file ${fileName} for the user with ID ${userId}.`, showConfirmButton: false, timer: 1800, toast: true, @@ -520,17 +572,20 @@ async function showFileInfo(fileLink) { console.log('Found fileInfo:', fileInfo); - let html = `

Nom du fichier : ${fileInfo.fileName}

`; + let html = `

File name: ${fileInfo.fileName}

`; if (fileInfo.expiryDate) { - html += `

Date de fin de disponibilité : ${fileInfo.expiryDate}

`; + html += `

Expiry date: ${fileInfo.expiryDate}

`; } if (fileInfo.password) { - html += `

Mot de passe : Oui

`; + html += `

Password: Yes

`; + } + if (fileInfo.userId) { + html += `

User: ${fileInfo.userId}

`; } Swal.fire({ - title: 'Informations sur le fichier', + title: 'File Information', html: html, - confirmButtonText: 'Fermer' + confirmButtonText: 'Close' }); } @@ -561,4 +616,4 @@ async function displayMetadata() { function closeModal() { const modal = document.getElementById('metadataModal'); modal.style.display = 'none'; -} +} \ No newline at end of file diff --git a/routes/Dpanel/API/GetMetaDataFile.js b/routes/Dpanel/API/GetMetaDataFile.js new file mode 100644 index 0000000..376b4a6 --- /dev/null +++ b/routes/Dpanel/API/GetMetaDataFile.js @@ -0,0 +1,53 @@ +const express = require('express'); +const fs = require('fs'); +const path = require('path'); +const router = express.Router(); +const fileUpload = require('express-fileupload'); +const authMiddleware = require('../../../Middlewares/authMiddleware'); +const { loggers } = require('winston'); +const ncp = require('ncp').ncp; +const configFile = fs.readFileSync(path.join(__dirname, '../../../data', 'setup.json'), 'utf-8') +const config = JSON.parse(configFile); +const bodyParser = require('body-parser'); +const crypto = require('crypto'); +const os = require('os'); +const { getUserData, getSetupData } = require('../../../Middlewares/watcherMiddleware'); +const { logger, logRequestInfo, ErrorLogger, authLogger } = require('../../../config/logs'); + +let setupData = getSetupData(); +let userData = getUserData(); +router.use(bodyParser.json()); + +router.get('/', (req, res) => { + res.status(400).json({ error: 'Bad Request. The request cannot be fulfilled due to bad syntax or missing parameters.' }); +}); + +router.post('/file_info', authMiddleware, (req, res) => { + const filePath = path.join(__dirname, '../../../data', 'file_info.json'); + + if (!fs.existsSync(filePath)) { + return res.status(404).json({ error: 'The specified file does not exist.' }); + } + + fs.readFile(filePath, 'utf-8', (err, data) => { + if (err) { + console.error(err); + return res.status(500).json({ error: 'Error reading the file.' }); + } + + const fileInfos = JSON.parse(data); + const fileLink = req.body.fileLink; + const fileName = fileLink.split('/').pop(); + + const fileInfo = fileInfos.find(file => file.fileName === fileName && file.Id); + console.log(fileInfos); + + if (!fileInfo) { + return res.status(404).json({ error: `No information found for the file ${fileName}.` }); + } + + res.json(fileInfo); + }); +}); + +module.exports = router; \ No newline at end of file diff --git a/routes/Dpanel/API/MoveFile.js b/routes/Dpanel/API/MoveFile.js index eaa4f3b..638008d 100644 --- a/routes/Dpanel/API/MoveFile.js +++ b/routes/Dpanel/API/MoveFile.js @@ -28,20 +28,24 @@ router.post('/', authMiddleware, async (req, res) => { const fileName = req.body.fileName; const folderName = req.body.folderName; + if (!fileName || fileName.trim() === '') { + return res.status(400).send('No file selected for moving.'); + } + const data = await fs.readFileSync(path.join(__dirname, '../../../data', 'user.json'), 'utf-8') const users = JSON.parse(data); const user = users.find(user => user.id === req.user.id); if (!user) { console.error('User not found in user.json'); - return res.status(500).send('Erreur lors du déplacement du fichier.'); + return res.status(500).send('Error moving the file.'); } const userId = user.name; if (!fileName || !userId) { console.error('fileName or userId is undefined'); - return res.status(500).send('Erreur lors du déplacement du fichier.'); + return res.status(500).send('Error moving the file.'); } const sourcePath = path.join('cdn-files', userId, fileName); @@ -72,7 +76,7 @@ router.post('/', authMiddleware, async (req, res) => { res.redirect('/dpanel/dashboard'); } catch (err) { console.error(err); - return res.status(500).send('Erreur lors du déplacement du fichier.'); + return res.status(500).send('Error moving the file.'); } }); @@ -84,7 +88,7 @@ router.post('/:folderName', authMiddleware, async (req, res) => { if (!fileName || !userId || !oldFolderName || !newFolderName) { console.error('fileName, userId, oldFolderName, or newFolderName is undefined'); - return res.status(500).send('Erreur lors du déplacement du fichier.'); + return res.status(500).send('Error moving the file.'); } const userDir = path.join(process.cwd(), 'cdn-files', userId); @@ -112,7 +116,7 @@ router.post('/:folderName', authMiddleware, async (req, res) => { res.redirect('/dpanel/dashboard'); } catch (err) { console.error(err); - return res.status(500).send('Erreur lors du déplacement du fichier.'); + return res.status(500).send('Error moving the file.'); } }); diff --git a/routes/Dpanel/API/Update-Setup-Admin.js b/routes/Dpanel/API/Update-Setup-Admin.js index 53a1aab..c1e3b9c 100644 --- a/routes/Dpanel/API/Update-Setup-Admin.js +++ b/routes/Dpanel/API/Update-Setup-Admin.js @@ -31,28 +31,31 @@ router.get('/', (req, res) => { }); +function clean(obj) { + for (var propName in obj) { + if (obj[propName] === null || obj[propName] === undefined || obj[propName] === '') { + delete obj[propName]; + } else if (typeof obj[propName] === 'object') { + clean(obj[propName]); + if (Object.keys(obj[propName]).length === 0) { + delete obj[propName]; + } + } + } +} + router.post('/', authMiddleware, async (req, res) => { try { - let setup = JSON.parse(fs.readFileSync(path.join(__dirname, '../data', 'setup.json'), 'utf-8')); - if (!req.body.ldap || !req.body.ldap.enabled) { - delete setup.ldap; - } else { - setup.ldap = req.body.ldap; - } + let setup = JSON.parse(fs.readFileSync(path.join(__dirname, '../../../data', 'setup.json'), 'utf-8')); - if (!req.body.discord || !req.body.discord.enabled) { - delete setup.discord; - } else { - setup.discord = req.body.discord; - } + clean(req.body); + setup[0] = req.body; - setup.domain = req.body.domain; - setup.uptime = req.body.uptime; - fs.writeFileSync(path.join(__dirname, '../../../data', 'setup.json'), 'utf-8'), JSON.stringify(setup, null, 2); + fs.writeFileSync(path.join(__dirname, '../../../data', 'setup.json'), JSON.stringify(setup, null, 2), 'utf-8'); - res.redirect('/dpanel/dashboard/admin'); + res.redirect('/dpanel/dashboard/admin/settingsetup'); } catch (err) { console.error(err); res.status(500).send('Server Error'); diff --git a/routes/Dpanel/Admin/SettingSetup.js b/routes/Dpanel/Admin/SettingSetup.js index c664b03..430f2c9 100644 --- a/routes/Dpanel/Admin/SettingSetup.js +++ b/routes/Dpanel/Admin/SettingSetup.js @@ -27,18 +27,25 @@ router.get('/', authMiddleware, async (req, res) => { try { const data = fs.readFileSync(path.join(__dirname, '../../../data', 'user.json'), 'utf8'); const users = JSON.parse(data); + console.log("Users:", users); const user = users.find(user => user.name === req.user.name); + console.log("Found user:", user); if (!user || user.role !== 'admin') { console.log('Access denied'); return res.status(403).json({ message: "You do not have the necessary rights to access this resource." }); } - res.render('paramAdminSettingSetup', { users: User, setup: setup }); + const setupData = fs.readFileSync(path.join(__dirname, '../../../data', 'setup.json'), 'utf8'); + const setup = JSON.parse(setupData); + console.log("Setup:", setup); + + res.render('paramAdminSettingSetup', { user: user, setup: setup[0] }); } catch (err) { console.error(err); res.status(500).send('Server Error'); } }); + module.exports = router; \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index 7fb32d2..aa73cbc 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,12 +1,8 @@ const express = require('express'); const router = express.Router(); const path = require('path'); -const { checkUpdates } = require('../Middlewares/checkUpdate'); -const { applyUpdate, restartCDN } = require('../models/updateManager'); const { logger, ErrorLogger, logRequestInfo } = require('../config/logs'); const util = require('util'); -const exec = util.promisify(require('child_process').exec); -const authMiddleware = require('../Middlewares/authMiddleware'); const fs = require('fs'); router.use(express.json()); @@ -19,57 +15,6 @@ router.get('/attachments', (req, res) => { res.render('acces-denied'); }); -router.get('/checkupdate',authMiddleware, checkUpdates); - -router.get('/applyupdate',authMiddleware, async (req, res) => { - const updateUrl = 'https://apollon.dinawo.fr/api/download/all'; - const updateFolder = path.join(__dirname, '..'); - - try { - logger.info('------Before applying the update------'); - await applyUpdate(updateUrl, updateFolder); - - logger.info('------After applying the update------'); - res.json({ - success: true, - message: 'Mise à jour appliquée avec succès. Pensé à redémarrer le serveur pour que la MàJ soit prise en compte. (systemctl restart cdn).' - }); - } catch (error) { - ErrorLogger.error('Error applying update:', error); - - return res.status(500).json({ success: false, message: 'Erreur lors de l\'application de la mise à jour.' }); - } -}); - -router.get('/translateAll', async (req, res) => { - const targetLanguage = req.query.lang || 'en'; - const viewsFolder = path.join(__dirname, '../views'); - - try { - const translatedFiles = []; - - const files = fs.readdirSync(viewsFolder); - for (const file of files) { - if (file.endsWith('.ejs')) { - const filePath = path.join(viewsFolder, file); - const translatedContent = await translateEJSFile(filePath, targetLanguage); - - if (translatedContent !== null) { - translatedFiles.push({ - fileName: file, - translatedContent, - }); - } - } - } - - res.json(translatedFiles); - } catch (error) { - console.error('Error translating all EJS files :', error.message); - res.status(500).json({ error: 'Translation mistake' }); - } -}); - router.get('/setup', (req, res) => { fs.readFile(path.join(__dirname, '../data/setup.json'), 'utf8', (err, data) => { if (err) { diff --git a/routes/routes.js b/routes/routes.js index 1794653..3313285 100644 --- a/routes/routes.js +++ b/routes/routes.js @@ -2,6 +2,7 @@ const express = require('express'); const router = express.Router(); const { logAndBanSuspiciousActivity } = require('../models/banModel.js'); const { logApiRequest } = require('../config/logs.js'); +const discordWebhookSuspisiousAlertMiddleware = require('../Middlewares/discordWebhookSuspisiousAlertMiddleware.js'); const indexRoute = require('./index.js'); const DpanelDashboardRoute = require('./Dpanel/Dashboard/index.js'); @@ -19,6 +20,7 @@ const UpdateRoleAdminRoute = require('./Dpanel/API/Upload-Role-Admin.js'); const UpdateSetupAdminRoute = require('./Dpanel/API/Update-Setup-Admin.js'); const DeleteFolderRoute = require('./Dpanel/API/DeleteFolfder.js'); const DeleteFileFolderRoute = require('./Dpanel/API/DeleteFileFolder.js'); +const GetMetaDataFileRoute = require('./Dpanel/API/GetMetaDataFile.js'); const loginRoute = require('./Auth/Login.js'); const logoutRoute = require('./Auth/Logout.js'); @@ -44,20 +46,21 @@ router.use('/dpanel/dashboard/admin/settingsetup', AdminSettingSetupDpanelRoute) router.use('/dpanel/dashboard/admin/stats-logs', AdminStatsLogsDpanelRoute);; router.use('/dpanel/dashboard/admin/Privacy-Security', AdminPrivacySecurityDpanelRoute); -router.use('/api/dpanel/dashboard/newfolder', logApiRequest, NewFolderRoute); -router.use('/api/dpanel/dashboard/rename', logApiRequest, RenameFileRoute); -router.use('/api/dpanel/dashboard/delete', logApiRequest, DeleteFileRoute); -router.use('/api/dpanel/dashboard/movefile', logApiRequest, MoveFileRoute); -router.use('/api/dpanel/upload', logApiRequest, UploadRoute); -router.use('/api/dpanel/dashboard/admin/update-role', logApiRequest, UpdateRoleAdminRoute); -router.use('/api/dpanel/dashboard/admin/update-setup', logApiRequest, UpdateSetupAdminRoute); -router.use('/api/dpanel/dashboard/deletefolder', logApiRequest, DeleteFolderRoute); -router.use('/api/dpanel/dashboard/deletefile/', logApiRequest,DeleteFileFolderRoute); +router.use('/api/dpanel/dashboard/newfolder',discordWebhookSuspisiousAlertMiddleware, logApiRequest, NewFolderRoute); +router.use('/api/dpanel/dashboard/rename',discordWebhookSuspisiousAlertMiddleware, logApiRequest, RenameFileRoute); +router.use('/api/dpanel/dashboard/delete',discordWebhookSuspisiousAlertMiddleware, logApiRequest, DeleteFileRoute); +router.use('/api/dpanel/dashboard/movefile',discordWebhookSuspisiousAlertMiddleware, logApiRequest, MoveFileRoute); +router.use('/api/dpanel/upload',discordWebhookSuspisiousAlertMiddleware, logApiRequest, UploadRoute); +router.use('/api/dpanel/dashboard/admin/update-role',discordWebhookSuspisiousAlertMiddleware, logApiRequest, UpdateRoleAdminRoute); +router.use('/api/dpanel/dashboard/admin/update-setup',discordWebhookSuspisiousAlertMiddleware, logApiRequest, UpdateSetupAdminRoute); +router.use('/api/dpanel/dashboard/deletefolder',discordWebhookSuspisiousAlertMiddleware, logApiRequest, DeleteFolderRoute); +router.use('/api/dpanel/dashboard/deletefile/', discordWebhookSuspisiousAlertMiddleware, logApiRequest,DeleteFileFolderRoute); +router.use('/api/dpanel/dashboard/getmetadatafile',discordWebhookSuspisiousAlertMiddleware, logApiRequest, GetMetaDataFileRoute); router.use('/auth/login', loginRoute); router.use('/auth/logout', logoutRoute); -router.use('/auth/activedirectory', activeDirectoryRoute); -router.use('/auth/discord', discordRoute); +router.use('/auth/activedirectory',discordWebhookSuspisiousAlertMiddleware, activeDirectoryRoute); +router.use('/auth/discord',discordWebhookSuspisiousAlertMiddleware, discordRoute); router.use('/*', logAndBanSuspiciousActivity, indexRoute); diff --git a/views/dashboard.ejs b/views/dashboard.ejs index eeddd1c..0d35707 100644 --- a/views/dashboard.ejs +++ b/views/dashboard.ejs @@ -90,7 +90,7 @@ <% files.forEach(file => { %> - <% if (fileInfoNames.includes(file.name) || file.name === 'mm4alktpmei71.jpg') { %> + <% if (fileInfoNames.includes(file.name)) { %> <%= file.name %> <% } else { %> <%= file.name %> @@ -167,33 +167,24 @@ +