From ec40145c69fed1e4ba6ba1f56c41ca94d0db2673 Mon Sep 17 00:00:00 2001 From: QkoSad Date: Mon, 14 Jul 2025 10:39:01 +0300 Subject: [PATCH] added node backend --- backend/db.js | 10 + backend/index.js | 21 + backend/package-lock.json | 953 ++++++++++++++++++++++++++ backend/package.json | 20 + backend/populateDB.js | 54 ++ backend/routers/getAll.js | 60 ++ backend/routers/getTopTen.js | 35 + backend/routers/getUser.js | 42 ++ backend/routers/reset.js | 16 + backend/sql/commands.sql | 137 ++++ backend/sql/current.sql | 147 ++++ backendCS.Tests/GlobalUsings.cs | 1 - backendCS.Tests/UnitTest1.cs | 158 ----- backendCS.Tests/backendCs.Test.csproj | 23 - backendCS/Program.cs | 122 ---- backendCS/Route.cs | 47 -- backendCS/TimelogBackend.csproj | 16 - backendCS/routes/CreateLog.cs | 134 ---- backendCS/routes/CreateProcedure.cs | 126 ---- backendCS/routes/Getall.cs | 126 ---- backendCS/routes/Gettopten.cs | 98 --- backendCS/routes/Getuser.cs | 59 -- backendCS/routes/Login.cs | 119 ---- backendCS/routes/Register.cs | 95 --- backendCS/routes/Reset.cs | 30 - backendCS/test.sh | 13 - 26 files changed, 1495 insertions(+), 1167 deletions(-) create mode 100644 backend/db.js create mode 100644 backend/index.js create mode 100644 backend/package-lock.json create mode 100644 backend/package.json create mode 100644 backend/populateDB.js create mode 100644 backend/routers/getAll.js create mode 100644 backend/routers/getTopTen.js create mode 100644 backend/routers/getUser.js create mode 100644 backend/routers/reset.js create mode 100644 backend/sql/commands.sql create mode 100644 backend/sql/current.sql delete mode 100644 backendCS.Tests/GlobalUsings.cs delete mode 100644 backendCS.Tests/UnitTest1.cs delete mode 100644 backendCS.Tests/backendCs.Test.csproj delete mode 100644 backendCS/Program.cs delete mode 100644 backendCS/Route.cs delete mode 100644 backendCS/TimelogBackend.csproj delete mode 100644 backendCS/routes/CreateLog.cs delete mode 100644 backendCS/routes/CreateProcedure.cs delete mode 100644 backendCS/routes/Getall.cs delete mode 100644 backendCS/routes/Gettopten.cs delete mode 100644 backendCS/routes/Getuser.cs delete mode 100644 backendCS/routes/Login.cs delete mode 100644 backendCS/routes/Register.cs delete mode 100644 backendCS/routes/Reset.cs delete mode 100755 backendCS/test.sh diff --git a/backend/db.js b/backend/db.js new file mode 100644 index 0000000..35443f4 --- /dev/null +++ b/backend/db.js @@ -0,0 +1,10 @@ +import mysql from "mysql2/promise"; + +const connection = await mysql.createConnection({ + host: "localhost", + user: "monty", + password: "some_pass", + database: "timelognode", +}); + +export default connection; diff --git a/backend/index.js b/backend/index.js new file mode 100644 index 0000000..aace694 --- /dev/null +++ b/backend/index.js @@ -0,0 +1,21 @@ +import express from "express"; +import getAll from "./routers/getAll.js"; +import getUser from "./routers/getUser.js"; +import getTopTen from "./routers/getTopTen.js"; +import reset from "./routers/reset.js"; +import cors from "cors"; + +const router = express.Router(); + +const app = express(); +app.use(express.json()); +app.use(cors()); + +app.use("/api", getAll); +app.use("/api", getTopTen); +app.use("/api", getUser); +app.use("/api", reset); + +app.use("/api", router); +const PORT = process.env.PORT || 5000; +app.listen(PORT, () => console.log(`Server started on port ${PORT}`)); diff --git a/backend/package-lock.json b/backend/package-lock.json new file mode 100644 index 0000000..90574cd --- /dev/null +++ b/backend/package-lock.json @@ -0,0 +1,953 @@ +{ + "name": "backend", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "backend", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "cors": "^2.8.5", + "express": "^4.21.1", + "mysql2": "^3.11.4" + }, + "devDependencies": { + "@types/node": "^22.9.0", + "typescript": "^5.6.3" + } + }, + "node_modules/@types/node": { + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", + "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.10", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "license": "MIT", + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "license": "MIT" + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/lru.min": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.1.tgz", + "integrity": "sha512-FbAj6lXil6t8z4z3j0E5mfRlPzxkySotzUHwRXjlpRh10vc6AI6WN62ehZj82VG7M20rqogJ0GLwar2Xa05a8Q==", + "license": "MIT", + "engines": { + "bun": ">=1.0.0", + "deno": ">=1.30.0", + "node": ">=8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wellwelwel" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/mysql2": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.11.4.tgz", + "integrity": "sha512-Z2o3tY4Z8EvSRDwknaC40MdZ3+m0sKbpnXrShQLdxPrAvcNli7jLrD2Zd2IzsRMw4eK9Yle500FDmlkIqp+krg==", + "license": "MIT", + "dependencies": { + "aws-ssl-profiles": "^1.1.1", + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru.min": "^1.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/mysql2/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "license": "MIT", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/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==", + "license": "MIT" + }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 0000000..63c9c9f --- /dev/null +++ b/backend/package.json @@ -0,0 +1,20 @@ +{ + "name": "backend", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "start": "node index.js" + }, + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "cors": "^2.8.5", + "express": "^4.21.1", + "mysql2": "^3.11.4" + }, + "devDependencies": { + "@types/node": "^22.9.0", + "typescript": "^5.6.3" + } +} diff --git a/backend/populateDB.js b/backend/populateDB.js new file mode 100644 index 0000000..4ff89ef --- /dev/null +++ b/backend/populateDB.js @@ -0,0 +1,54 @@ +fnameS = [ + "John", + "Gringo", + "Mark", + "Lisa", + "Maria", + "Sonya", + "Philip", + "Jose", + "Lorenzo", + "George", + "Justin", +]; + +lnameS = [ + "Johnson", + "Lamas", + "Jackson", + "Brown", + "Mason", + "Rodriguez", + "Roberts", + "Thomas", + "Rose", + "McDonalds", +]; + +domain = ["hotmail.com", "gmail.com", "live.com"]; +fname = []; +lname = []; +email = []; +i = 0; +while (i < 100) { + fname.push(fnameS[Math.floor(Math.random() * 10)]); + lname.push(lnameS[Math.floor(Math.random() * 9)]); + email.push( + `${fname[i]}.${lname[i]}@${domain[Math.floor(Math.random() * 2)]}`, + ); + i++; +} + +today = new Date(); +for (let i = 0; i < email.length; i++) { + for (let j = 0; j < Math.floor(Math.random() * 20); j++) { + let m = Math.random() * (8 - 0.25) + 0.25; + m.toFixed(2); + console.log( + fname[i], + m, + `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`, + ); + today.setDate(today.getDate() + 1); + } +} diff --git a/backend/routers/getAll.js b/backend/routers/getAll.js new file mode 100644 index 0000000..561a22a --- /dev/null +++ b/backend/routers/getAll.js @@ -0,0 +1,60 @@ +import express from "express"; +import connection from "../db.js"; + +const router = express.Router(); + +router.get("/getall", async (req, res) => { + let sql = + "SELECT u.f_name,u.l_name,u.mail,p.name,t.time,t.date,t.user \ + FROM Timelog t \ + INNER JOIN Project p ON p.id=t.project \ + INNER JOIN User u ON u.id=t.user "; + const where = "WHERE t.date BETWEEN ? AND ? "; + const order = "ORDER BY ?? "; + const offsetSql = "LIMIT 10 OFFSET ?;"; + let flag = 0; + // construct the sql statement based on incoming request + if (req.query.from || req.query.to) { + sql = sql + where; + flag += 1; + } + if (req.query.sortby) { + sql = sql + order; + flag += 2; + } + sql = sql + offsetSql; + + let results; + let fields; + switch (flag) { + case 0: + [results, fields] = await connection.query(sql, [ + parseInt(req.query.offset), + ]); + break; + case 1: + [results, fields] = await connection.query(sql, [ + req.query.from, + req.query.to, + parseInt(req.query.offset), + ]); + break; + case 2: + [results, fields] = await connection.query(sql, [ + req.query.sortby, + parseInt(req.query.offset), + ]); + break; + case 3: + [results, fields] = await connection.query(sql, [ + req.query.from, + req.query.to, + req.query.sortby, + parseInt(req.query.offset), + ]); + break; + } + res.json(results); +}); + +export default router; diff --git a/backend/routers/getTopTen.js b/backend/routers/getTopTen.js new file mode 100644 index 0000000..e1b030e --- /dev/null +++ b/backend/routers/getTopTen.js @@ -0,0 +1,35 @@ +import express from "express"; +import connection from "../db.js"; + +const router = express.Router(); + +router.get("/gettopten", async (req, res) => { + let from = "2020-01-01"; + let to = "2029-01-01"; + let filterBy = "user"; + if (req.query.from) from = req.query.from; + if (req.query.to) to = req.query.to; + if (req.query.filterBy) filterBy = req.query.filterBy; + let results, fields; + let filterBySql = filterBy === "user" ? "t.user" : "t.project"; + try { + [results, fields] = await connection.query( + "SELECT t.user,t.date,t.project,u.f_name,u.l_name,p.name,SUM(t.time) as total_time \ + FROM Timelog t \ + INNER JOIN Project p ON p.id=t.project \ + INNER JOIN User u ON u.id=t.user \ + WHERE t.date BETWEEN ? AND ? \ + GROUP BY ?? \ + ORDER BY total_time DESC\ + LIMIT 10;", + [from, to, filterBySql], + ); + } catch (err) { + console.log(err); + res.status(400).json({ message: "Error" }); + } + + res.json(results); +}); + +export default router; diff --git a/backend/routers/getUser.js b/backend/routers/getUser.js new file mode 100644 index 0000000..b52b3b3 --- /dev/null +++ b/backend/routers/getUser.js @@ -0,0 +1,42 @@ +import express from "express"; +import connection from "../db.js"; + +const router = express.Router(); + +router.get("/getUser", async (req, res) => { + const userId = req.query.userid; + let results, fields; + try { + [results, fields] = await connection.query( + "SELECT p.name,t.time,t.project \ + FROM Timelog t \ + INNER JOIN Project p ON p.id=t.project \ + INNER JOIN User u ON u.id=t.user \ + WHERE USER = ? ;", + [userId], + ); + } catch (err) { + console.log(err); + res.status(400).json("ERROR"); + } + let projects = {}; + let projectIdtoName = {}; + for (let i = 0; i < results.length; i++) { + if (results[i].project in projects) { + projects[results[i].project] += results[i].time; + } else { + projects[results[i].project] = results[i].time; + projectIdtoName[results[i].project] = results[i].name; + } + } + // map projectIds to project names before sending the data + let respData = {}; + for (let key in projects) { + if (projects.hasOwnProperty(key)) { + respData[projectIdtoName[key]] = projects[key]; + } + } + res.json(respData); +}); + +export default router; diff --git a/backend/routers/reset.js b/backend/routers/reset.js new file mode 100644 index 0000000..50400fe --- /dev/null +++ b/backend/routers/reset.js @@ -0,0 +1,16 @@ +import express from "express"; +import connection from "../db.js"; + +const router = express.Router(); + +router.get("/reset", async (req, res) => { + try { + await connection.query("CALL InitDb;", []); + } catch (err) { + console.log(err); + res.status(400).json({ message: "Error" }); + } + res.status(200).json({ message: "Success" }); +}); + +export default router; diff --git a/backend/sql/commands.sql b/backend/sql/commands.sql new file mode 100644 index 0000000..e4dfe67 --- /dev/null +++ b/backend/sql/commands.sql @@ -0,0 +1,137 @@ +CREATE TABLE Timelog( user INT, project INT, date DATE, time FLOAT, id INT AUTO_INCREMENT PRIMARY KEY, FOREIGN KEY (user) REFERENCES User (id)); +CREATE TABLE Project( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50)); +CREATE TABLE User ( f_name VARCHAR(50) , l_name VARCHAR(50) NOT NULL, mail VARCHAR(50) NOT NULL, id INT AUTO_INCREMENT PRIMARY KEY); + +#### +DELIMITER // + +CREATE PROCEDURE InsertIntoUser(IN f_name_in VARCHAR(50), IN l_name_in VARCHAR(50), IN mail_in VARCHAR(50)) +BEGIN + INSERT INTO User(f_name,l_name,mail) VALUES(f_name_in,l_name_in,mail_in); +END // + +DELIMITER ; + +###### +DELIMITER // + +CREATE PROCEDURE InsertIntoProject() +BEGIN + INSERT INTO Project(name) VALUES("My own"); + INSERT INTO Project(name) VALUES("Outcons"); + INSERT INTO Project(name) VALUES("Free time"); +END // + +DELIMITER ; + +#### +DELIMITER // + +CREATE PROCEDURE InsertIntoTimeLog(IN user_in INT, IN project_in INT, IN time_in FLOAT, IN date_in DATE) +BEGIN + INSERT INTO Timelog(user, project, time, date) VALUES(user_in, project_in, time_in, date_in); +END // + +DELIMITER ; + +#### +DELIMITER // + +CREATE PROCEDURE CleanTables() +BEGIN + TRUNCATE TABLE Timelog; + TRUNCATE TABLE Project; + SET foreign_key_checks = 0; + TRUNCATE TABLE User; + SET foreign_key_checks = 1; +END // + +DELIMITER ; + +SELECT ROUTINE_NAME +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_TYPE = 'PROCEDURE' + AND ROUTINE_SCHEMA = 'timelog'; + +################ + +CREATE TEMPORARY TABLE temp_fname (fname VARCHAR(255)); +INSERT INTO temp_fname (fname) VALUES + ( "John" ), + ( "Gringo" ), + ( "Mark" ), + ( "Lisa" ), + ( "Maria" ), + ( "Sonya" ), + ( "Philip" ), + ( "Jose" ), + ( "Lorenzo" ), + ( "George" ), + ( "Justin" ); + +CREATE TEMPORARY TABLE temp_lname (lname VARCHAR(255)); +INSERT INTO temp_lname (lname) VALUES + ( "Johnson" ), + ( "Lamas" ), + ( "Jackson" ), + ( "Brown" ), + ( "Mason" ), + ( "Rodriguez" ), + ( "Roberts" ), + ( "Thomas" ), + ( "Rose" ), + ( "McDonalds" ); + +CREATE TEMPORARY TABLE temp_mail (mail VARCHAR(255)); +INSERT INTO temp_mail (mail) VALUES + ( "hotmail.com" ), + ( "gmail.com" ), + ( "live.com" ); + +INSERT INTO User (f_name, l_name, mail) +SELECT + (SELECT fname FROM temp_fname ORDER BY RAND() LIMIT 1), + (SELECT lname FROM temp_lname ORDER BY RAND() LIMIT 1), + (SELECT mail FROM temp_mail ORDER BY RAND() LIMIT 1) +FROM + (SELECT 1 FROM information_schema.tables LIMIT 100) AS temp; + +UPDATE User +SET User.mail = CONCAT(User.f_name,".", User.l_name,"@", User.mail); + +DELIMITER $$ + +CREATE PROCEDURE fill_timelog () +BEGIN + DECLARE j INT DEFAULT 1; + DECLARE users INT DEFAULT 1; + DECLARE logs INT; + DECLARE hours FLOAT; + DECLARE project INT; + DECLARE curDate DATE DEFAULT "2024-11-18"; + +WHILE users <= 100 DO + SET logs = FLOOR(1+(RAND()*20)); + SET j=1; + WHILE j <= logs DO + SET hours = (RAND() * (8 - 0.25)) + 0.25; + SET curDate = DATE_ADD(curDate, INTERVAL 1 DAY); + SET project = FLOOR(1+(RAND()*3)); + INSERT INTO Timelog (user, project, date,time ) VALUES (users,project,curDate,hours); + SET j=j+1; + END WHILE; + SET users=users+1; +END WHILE; +END$$ + +DELIMITER ; + + + SELECT t.user,t.date,t.project,u.f_name,u.l_name,p.name,SUM(t.time) as total_time + FROM Timelog t + INNER JOIN Project p ON p.id=t.project + INNER JOIN User u ON u.id=t.user + GROUP BY t.user + ORDER BY total_time DESC + LIMIT 10; + diff --git a/backend/sql/current.sql b/backend/sql/current.sql new file mode 100644 index 0000000..14b9b21 --- /dev/null +++ b/backend/sql/current.sql @@ -0,0 +1,147 @@ +CREATE TABLE User ( f_name VARCHAR(50) , l_name VARCHAR(50) NOT NULL, mail VARCHAR(50) NOT NULL, id INT AUTO_INCREMENT PRIMARY KEY); +CREATE TABLE Timelog( user INT, project INT, date DATE, time FLOAT, id INT AUTO_INCREMENT PRIMARY KEY, FOREIGN KEY (user) REFERENCES User (id)); +CREATE TABLE Project( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50)); + + +DELIMITER $$ + +CREATE PROCEDURE CleanTables() +BEGIN +END $$ + +DELIMITER ; + + +DELIMITER $$ +CREATE PROCEDURE InitDB() +BEGIN +DECLARE i INT DEFAULT 1; +TRUNCATE TABLE Timelog; +TRUNCATE TABLE Project; +SET foreign_key_checks = 0; +TRUNCATE TABLE User; +SET foreign_key_checks = 1; + +INSERT INTO Project(name) VALUES("My own"),("Outcons"),("Free Time"); + +CREATE TEMPORARY TABLE temp_fname (fname VARCHAR(255)); +INSERT INTO temp_fname (fname) VALUES + ( "John" ), + ( "Gringo" ), + ( "Mark" ), + ( "Lisa" ), + ( "Maria" ), + ( "Sonya" ), + ( "Philip" ), + ( "Jose" ), + ( "Lorenzo" ), + ( "George" ), + ( "Justin" ); + +CREATE TEMPORARY TABLE temp_lname (lname VARCHAR(255)); +INSERT INTO temp_lname (lname) VALUES + ( "Johnson" ), + ( "Lamas" ), + ( "Jackson" ), + ( "Brown" ), + ( "Mason" ), + ( "Rodriguez" ), + ( "Roberts" ), + ( "Thomas" ), + ( "Rose" ), + ( "McDonalds" ); + +CREATE TEMPORARY TABLE temp_mail (mail VARCHAR(255)); +INSERT INTO temp_mail (mail) VALUES + ( "hotmail.com" ), + ( "gmail.com" ), + ( "live.com" ); + +WHILE i <= 100 DO + INSERT INTO User (f_name, l_name, mail) + SELECT + (SELECT fname FROM temp_fname ORDER BY RAND() LIMIT 1), + (SELECT lname FROM temp_lname ORDER BY RAND() LIMIT 1), + (SELECT mail FROM temp_mail ORDER BY RAND() LIMIT 1); + SET i = i + 1; +END WHILE; + +UPDATE User +SET User.mail = CONCAT(User.f_name,".", User.l_name,"@", User.mail); + +CALL fill_timelog(); +DROP TABLE temp_mail; +DROP TABLE temp_fname; +DROP TABLE temp_lname; +END$$ +DELIMITER ; + +DELIMITER $$ + +CREATE PROCEDURE fill_timelog () +BEGIN + DECLARE j INT DEFAULT 1; + DECLARE users INT DEFAULT 1; + DECLARE logs INT; + DECLARE hours FLOAT; + DECLARE project INT; + DECLARE curDate DATE DEFAULT '2024-11-18'; + DECLARE h2 INT; + +WHILE users <= 100 DO + SET logs = FLOOR(1+(RAND()*20)); + SET j=1; + WHILE j <= logs DO + SET project = FLOOR(1+(RAND()*3)); + SET curDate = DATE_ADD('2020-01-01', INTERVAL FLOOR(RAND() * DATEDIFF('2020-02-01', '2020-01-01')) DAY); + SET hours = (RAND() * (8 - 0.25)) + 0.25; + + SELECT SUM(time) INTO h2 + FROM Timelog + WHERE date = curdate && user = users ; + + WHILE (h2+hours) > 8 DO + SET curDate = DATE_ADD('2020-01-01', INTERVAL FLOOR(RAND() * DATEDIFF('2020-02-01', '2020-01-01')) DAY); + + SELECT SUM(time)INTO h2 + FROM Timelog + WHERE date = curdate && user = users ; + + END WHILE; + INSERT INTO Timelog (user, project, date,time ) VALUES (users,project,curDate,hours); + SET j=j+1; + END WHILE; + SET users=users+1; +END WHILE; +END$$ + +DELIMITER ; + +## +-- get data +SELECT t.time,t.date,p.name,u.f_name,u.l_name,u.mail FROM Timelog t INNER JOIN Project p ON p.id=t.project INNER JOIN User u ON u.id=t.user; +-- old timelog with adding each on a new day +CREATE PROCEDURE fill_timelog () +BEGIN + DECLARE j INT DEFAULT 1; + DECLARE users INT DEFAULT 1; + DECLARE logs INT; + DECLARE hours FLOAT; + DECLARE project INT; + DECLARE curDate DATE DEFAULT "2024-11-18"; + +WHILE users <= 100 DO + SET logs = FLOOR(1+(RAND()*20)); + SET j=1; + WHILE j <= logs DO + SET hours = (RAND() * (8 - 0.25)) + 0.25; + SET project = FLOOR(1+(RAND()*3)); + SET curDate = DATE_ADD(curDate, INTERVAL 1 DAY); + INSERT INTO Timelog (user, project, date,time ) VALUES (users,project,curDate,hours); + SET j=j+1; + END WHILE; + SET users=users+1; +END WHILE; +END$$ + +DELIMITER ; diff --git a/backendCS.Tests/GlobalUsings.cs b/backendCS.Tests/GlobalUsings.cs deleted file mode 100644 index ab67c7e..0000000 --- a/backendCS.Tests/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file diff --git a/backendCS.Tests/UnitTest1.cs b/backendCS.Tests/UnitTest1.cs deleted file mode 100644 index 2bb7fc4..0000000 --- a/backendCS.Tests/UnitTest1.cs +++ /dev/null @@ -1,158 +0,0 @@ -namespace backendCs.Test; - -using System.Net.Http; -using System.Text; - -[TestClass] -public class UnitTest1 -{ - [TestMethod] - public async Task TestMethodReset() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync("http://localhost:5000/api/reset"); - - Assert.AreEqual((int)response.StatusCode, 200); - } - - [TestMethod] - public async Task TestMethodGetall1() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync( - "http://localhost:5000/api/getall?offset=10" - ); - - Assert.AreEqual((int)response.StatusCode, 200); - } - - [TestMethod] - public async Task TestMethodGetall2() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync( - "http://localhost:5000/api/getall?offset=" - ); - - Assert.AreEqual((int)response.StatusCode, 400); - } - - [TestMethod] - public async Task TestMethodGetall3() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync( - "http://localhost:5000/api/getall?offset=10&from=2020-01-01&to=2024-01-01&orderby=time&order=true" - ); - - Assert.AreEqual((int)response.StatusCode, 200); - } - - [TestMethod] - public async Task TestMethodGettopten1() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync( - "http://localhost:5000/api/gettopten?from=2000-01-01&to=2024-01-01&filterby=project" - ); - - Assert.AreEqual((int)response.StatusCode, 200); - } - - [TestMethod] - public async Task TestMethodGettopten2() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync( - "http://localhost:5000/api/gettopten?from=2000-01-01&to=2024-01-01&filterby=user" - ); - - Assert.AreEqual((int)response.StatusCode, 200); - } - - [TestMethod] - public async Task TestMethodGettopten3() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync( - "http://localhost:5000/api/gettopten?to=2024-01-01&filterby=project" - ); - - Assert.AreEqual((int)response.StatusCode, 400); - } - - [TestMethod] - public async Task TestMethodGettopten4() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync( - "http://localhost:5000/api/gettopten?from=2000-01-01&filterby=project" - ); - - Assert.AreEqual((int)response.StatusCode, 400); - } - - [TestMethod] - public async Task TestMethodGettopten5() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync( - "http://localhost:5000/api/gettopten?from=2000-01-01&to=2024-01-01" - ); - - Assert.AreEqual((int)response.StatusCode, 400); - } - - [TestMethod] - public async Task TestMethodGetuser1() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync( - "http://localhost:5000/api/getuser?userid=1" - ); - - Assert.AreEqual((int)response.StatusCode, 200); - } - - [TestMethod] - public async Task TestMethodGetuser2() - { - using HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync("http://localhost:5000/api/getuser"); - - Assert.AreEqual((int)response.StatusCode, 400); - } - - [TestMethod] - public async Task TestMethodRegister1() - { - using HttpClient client = new(); - // Make a GET request to a URL - var jsonData = - "{ \"f_name\": \"donna\", \"l_name\": \"cow\", \"mail\": \"tombo@mail.com\", \"password\": \"1234567890\" }"; - var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); - - HttpResponseMessage response = await client.PostAsync( - "http://localhost:5000/api/register", - content - ); - - Assert.AreEqual((int)response.StatusCode, 200); - } - - [TestMethod] - public async Task TestMethodLogin() - { - using HttpClient client = new(); - // Make a GET request to a URL - var jsonData = "{ \"mail\": \"tombo@mail.com\", \"password\": \"1234567890\" }"; - var content = new StringContent(jsonData, Encoding.UTF8, "application/json"); - - HttpResponseMessage response = await client.PostAsync( - "http://localhost:5000/api/login", - content - ); - - Assert.AreEqual((int)response.StatusCode, 200); - } -} diff --git a/backendCS.Tests/backendCs.Test.csproj b/backendCS.Tests/backendCs.Test.csproj deleted file mode 100644 index 30aa586..0000000 --- a/backendCS.Tests/backendCs.Test.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - net8.0 - enable - enable - - false - true - - - - - - - - - - - - - - diff --git a/backendCS/Program.cs b/backendCS/Program.cs deleted file mode 100644 index 77d622f..0000000 --- a/backendCS/Program.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System.Net; -using System.Text; - -namespace TimelogBackend; - -class Program -{ - static void Main() - { - // create server - HttpListener listener = new(); - // routes need to be added first - listener.Prefixes.Add("http://localhost:5000/api/getall/"); - listener.Prefixes.Add("http://localhost:5000/api/gettopten/"); - listener.Prefixes.Add("http://localhost:5000/api/getuser/"); - listener.Prefixes.Add("http://localhost:5000/api/reset/"); - listener.Prefixes.Add("http://localhost:5000/api/createp/"); - listener.Prefixes.Add("http://localhost:5000/api/register/"); - listener.Prefixes.Add("http://localhost:5000/api/login/"); - listener.Prefixes.Add("http://localhost:5000/api/createlog/"); - - // listen - listener.Start(); - Console.WriteLine("Server is listening on http://localhost:5000/"); - while (true) - { - HttpListenerContext context = listener.GetContext(); - HttpListenerRequest request = context.Request; - HttpListenerResponse response = context.Response; - response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:5173"); - response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); - response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization"); - - // url after localhost:5000/ - string uri; - if (request != null && request.Url != null) - uri = request.Url.AbsolutePath; - else - return; - switch (request.HttpMethod) - { - case "GET": - HandleGet(uri, request, response); - break; - case "POST": - HandlePost(uri, request, response); - break; - default: - HandleMissingPath(response); - break; - } - } - } - - private static void HandlePost( - string uri, - HttpListenerRequest request, - HttpListenerResponse response - ) - { - if (request.HasEntityBody) - switch (uri) - { - case "/api/register": - Register.HandleRequest(request, response); - break; - case "/api/login": - Login.HandleRequest(request, response); - break; - case "/api/createlog": - CreateLog.HandleRequest(request, response); - break; - default: - HandleMissingPath(response); - break; - } - else - { - HandleMissingPath(response); - } - } - - private static void HandleGet( - string uri, - HttpListenerRequest request, - HttpListenerResponse response - ) - { - switch (uri) - { - case "/api/reset": - Reset.HandleRequest(response); - break; - case "/api/getall": - Getall.HandleRequest(request, response); - break; - case "/api/gettopten": - Gettopten.HandleRequest(request, response); - break; - case "/api/getuser": - Getuser.HandleRequest(request, response); - break; - case "/api/createp": - CreateProcedure.HandleRequest(response); - break; - default: - HandleMissingPath(response); - break; - } - } - - private static void HandleMissingPath(HttpListenerResponse response) - { - response.StatusCode = 404; - string errorMessage = "Not Found"; - byte[] buffer = Encoding.UTF8.GetBytes(errorMessage); - response.ContentType = "text/plain"; - response.ContentLength64 = buffer.Length; - response.OutputStream.Write(buffer, 0, buffer.Length); - response.OutputStream.Write(buffer, 0, buffer.Length); - } -} diff --git a/backendCS/Route.cs b/backendCS/Route.cs deleted file mode 100644 index ad80a69..0000000 --- a/backendCS/Route.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Net; -using System.Text; -using System.Text.RegularExpressions; - -namespace TimelogBackend; - -public abstract class Route -{ - public static string connectionString = - "server=127.0.0.1;uid=monty;pwd=some_pass;database=timelog"; - - public static void SendError(HttpListenerResponse response, Exception ex) - { - response.StatusCode = (int)HttpStatusCode.BadRequest; - string errorMessage = $"Error: {ex.Message}"; - byte[] buffer = Encoding.UTF8.GetBytes(errorMessage); - response.ContentType = "text/plain"; - response.ContentLength64 = buffer.Length; - response.OutputStream.Write(buffer, 0, buffer.Length); - response.Close(); - } - - public static void SendSuccess(HttpListenerResponse response) - { - response.StatusCode = (int)HttpStatusCode.OK; - response.StatusDescription = "Status OK"; - response.Close(); - } - - public static void SendSuccess(HttpListenerResponse response, string jsonResponse) - { - response.StatusCode = (int)HttpStatusCode.OK; - response.StatusDescription = "Status OK"; - byte[] buffer = Encoding.UTF8.GetBytes(jsonResponse); - response.ContentType = "application/json"; - response.ContentLength64 = buffer.Length; - response.OutputStream.Write(buffer, 0, buffer.Length); - response.Close(); - } - - public static bool ValidateDate(string date) - { - Regex regex = new(@"^\d{4}-\d{2}-\d{2}$"); - return regex.IsMatch(date); - } - /* public virtual void run(MySqlConnection conn, HttpListenerRequest request, HttpListenerResponse response) { } */ -} diff --git a/backendCS/TimelogBackend.csproj b/backendCS/TimelogBackend.csproj deleted file mode 100644 index 7b59323..0000000 --- a/backendCS/TimelogBackend.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - diff --git a/backendCS/routes/CreateLog.cs b/backendCS/routes/CreateLog.cs deleted file mode 100644 index be41d94..0000000 --- a/backendCS/routes/CreateLog.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Net; -using System.Text; -using System.Text.RegularExpressions; -using Microsoft.IdentityModel.Tokens; -using MySql.Data.MySqlClient; -using Newtonsoft.Json.Linq; - -namespace TimelogBackend; - -public class CreateLog : Route -{ - private static readonly string secretKey = - "stronk-key-much-sercret-much-more-stronk-stronk-key-much-sercret-much-more-stronk"; - - public static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response) - { - try - { - // check header - var headers = request.Headers; - string token = headers["token"] ?? ""; - if (!string.IsNullOrEmpty(token) && !ValidateToken(token)) - { - throw new Exception("Invalid token"); - } - - MySqlCommand cmd = new(); - - string body; - using (StreamReader bodyReader = new(request.InputStream, request.ContentEncoding)) - { - body = bodyReader.ReadToEnd(); - } - JObject jsonObject = JObject.Parse(body); - string project = jsonObject["project"]?.ToString() ?? ""; - string time = jsonObject["time"]?.ToString() ?? ""; - string date = jsonObject["date"]?.ToString() ?? ""; - - // TODO check if the hours on given date don't combine to more - // than 8 - - if (!ValidateTime(time)) - { - throw new Exception("Incorrect date format"); - } - if (!ValidateDate(date)) - { - throw new Exception("Incorrect date format"); - } - // validate user - string? usernameClaim = GetUserFromToken(token); - if (string.IsNullOrEmpty(usernameClaim)) - { - throw new Exception("wrong user id"); - } - // validate project - // TODO better project validation - if (string.IsNullOrEmpty(project)) - { - throw new Exception("wrong project"); - } - SaveTimeLogToDatabase(usernameClaim, project, date, time); - SendSuccess(response); - } - catch (Exception ex) - { - SendError(response, ex); - } - } - - private static bool ValidateToken(string token) - { - try - { - var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)); - var tokenHandler = new JwtSecurityTokenHandler(); - var validationParameters = new TokenValidationParameters - { - ValidateIssuer = true, - ValidateAudience = true, - ValidateLifetime = true, - ValidIssuer = "TimeLogServer", - ValidAudience = "TimeLogWebsite", - IssuerSigningKey = key, - }; - - var principal = tokenHandler.ValidateToken( - token, - validationParameters, - out SecurityToken validatedToken - ); - return validatedToken != null; - } - catch - { - return false; - } - } - - private static bool ValidateTime(string time) - { - return int.TryParse(time, out int myInt) && myInt >= 0 && myInt <= 8; - } - - private static string GetUserFromToken(string token) - { - var handler = new JwtSecurityTokenHandler(); - var jwtToken = handler.ReadJwtToken(token); - string? usernameClaim = jwtToken.Claims.FirstOrDefault(c => c.Type == "user")?.Value; - return string.IsNullOrEmpty(usernameClaim) ? "" : usernameClaim; - } - - private static void SaveTimeLogToDatabase( - string username, - string project, - string date, - string time - ) - { - using MySqlConnection conn = new(connectionString); - conn.Open(); - using MySqlCommand cmd = new( - @"INSERT INTO Timelog(user, project, date, time) - VALUES(@user, @project, @date, @time);", - conn - ); - cmd.Parameters.AddWithValue("@user", username); - cmd.Parameters.AddWithValue("@project", project); - cmd.Parameters.AddWithValue("@date", date); - cmd.Parameters.AddWithValue("@time", time); - cmd.ExecuteNonQuery(); - } -} diff --git a/backendCS/routes/CreateProcedure.cs b/backendCS/routes/CreateProcedure.cs deleted file mode 100644 index 074a2ff..0000000 --- a/backendCS/routes/CreateProcedure.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System.Net; -using MySql.Data.MySqlClient; - -namespace TimelogBackend; - -public class CreateProcedure : Route -{ - public static void HandleRequest(HttpListenerResponse response) - { - try - { - MySqlCommand cmd = new(); - - using MySqlConnection conn = new(connectionString); - conn.Open(); - cmd.Connection = conn; - cmd.CommandText = - @" CREATE PROCEDURE fill_timelog () - BEGIN - DECLARE j INT DEFAULT 1; - DECLARE users INT DEFAULT 1; - DECLARE logs INT; - DECLARE hours FLOAT; - DECLARE project INT; - DECLARE curDate DATE DEFAULT '2024-11-18'; - DECLARE h2 INT; - - WHILE users <= 100 DO - SET logs = FLOOR(1 + (RAND() * 20)); - SET j = 1; - WHILE j <= logs DO - SET project = FLOOR(1 + (RAND() * 3)); - SET curDate = DATE_ADD('2020-01-01', INTERVAL FLOOR(RAND() * DATEDIFF('2020-02-01', '2020-01-01')) DAY); - SET hours = (RAND() * (8 - 0.25)) + 0.25; - - SELECT SUM(time) INTO h2 - FROM Timelog - WHERE date = curdate && user = users; - - WHILE(h2 + hours) > 8 DO - SET curDate = DATE_ADD('2020-01-01', INTERVAL FLOOR(RAND() * DATEDIFF('2020-02-01', '2020-01-01')) DAY); - - SELECT SUM(time)INTO h2 - FROM Timelog - WHERE date = curdate && user = users; - - END WHILE; - INSERT INTO Timelog(user, project, date, time) VALUES(users, project, curDate, hours); - SET j = j + 1; - END WHILE; - SET users = users + 1; - END WHILE; - END;"; - cmd.ExecuteNonQuery(); - cmd.CommandText = - @"CREATE PROCEDURE InitDB() - BEGIN - DECLARE i INT DEFAULT 1; - TRUNCATE TABLE Timelog; - TRUNCATE TABLE Project; - SET foreign_key_checks = 0; - TRUNCATE TABLE User; - SET foreign_key_checks = 1; - - INSERT INTO Project(name) VALUES('My own'),('Outcons'),('Free Time'); - - CREATE TEMPORARY TABLE temp_fname (fname VARCHAR(255)); - INSERT INTO temp_fname (fname) VALUES - ( 'John' ), - ( 'Gringo' ), - ( 'Mark' ), - ( 'Lisa' ), - ( 'Maria' ), - ( 'Sonya' ), - ( 'Philip' ), - ( 'Jose' ), - ( 'Lorenzo' ), - ( 'George' ), - ( 'Justin' ); - - CREATE TEMPORARY TABLE temp_lname (lname VARCHAR(255)); - INSERT INTO temp_lname (lname) VALUES - ( 'Johnson' ), - ( 'Lamas' ), - ( 'Jackson' ), - ( 'Brown' ), - ( 'Mason' ), - ( 'Rodriguez' ), - ( 'Roberts' ), - ( 'Thomas' ), - ( 'Rose' ), - ( 'McDonalds' ); - - CREATE TEMPORARY TABLE temp_mail (mail VARCHAR(255)); - INSERT INTO temp_mail (mail) VALUES - ( 'hotmail.com' ), - ( 'gmail.com' ), - ( 'live.com' ); - - WHILE i <= 100 DO - INSERT INTO User (f_name, l_name, mail) - SELECT - (SELECT fname FROM temp_fname ORDER BY RAND() LIMIT 1), - (SELECT lname FROM temp_lname ORDER BY RAND() LIMIT 1), - (SELECT mail FROM temp_mail ORDER BY RAND() LIMIT 1); - SET i = i + 1; - END WHILE; - - UPDATE User - SET User.mail = CONCAT(User.f_name,'.', User.l_name,'@', User.mail); - - CALL fill_timelog(); - DROP TABLE temp_mail; - DROP TABLE temp_fname; - DROP TABLE temp_lname; - END;"; - cmd.ExecuteNonQuery(); - // prepare response - SendSuccess(response); - } - catch (Exception ex) - { - SendError(response, ex); - } - } -} diff --git a/backendCS/routes/Getall.cs b/backendCS/routes/Getall.cs deleted file mode 100644 index c0cf49a..0000000 --- a/backendCS/routes/Getall.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System.Net; -using MySql.Data.MySqlClient; -using Newtonsoft.Json; - -namespace TimelogBackend; - -// there should be a better way to deal with data comming from sql -public class Log -{ - public object? FName { get; set; } - public object? LName { get; set; } - public object? Mail { get; set; } - public object? Name { get; set; } - public object? Time { get; set; } - public object? Date { get; set; } - public object? User { get; set; } -} - -public class Getall : Route -{ - private static string ConstructQuery( - string from, - string to, - string order, - string offset, - string sortby - ) - { - string mainQuery = - @"SELECT u.f_name,u.l_name,u.mail,p.name,t.time,t.date,t.user - FROM Timelog t - INNER JOIN Project p ON p.id=t.project - INNER JOIN User u ON u.id=t.user "; - // this shenanigan is needed to remove the "" around group by - string offsetQuery = " LIMIT 10 OFFSET " + offset + ";"; - // depending on the incoming parameters construct a Query - if (!string.IsNullOrEmpty(to) && !string.IsNullOrEmpty(from)) - { - mainQuery += AddWhereClause(from, to); - } - if (!string.IsNullOrEmpty(sortby)) - { - mainQuery += AddSortBy(sortby, order); - } - if (!int.TryParse(offset, out int myInt) || myInt < 0) - throw new Exception("Incorect offset"); - - return mainQuery + offsetQuery; - } - - private static string AddWhereClause(string from, string to) - { - if (!ValidateDate(to) || !ValidateDate(from)) - { - throw new Exception("Incorrect date format"); - } - string whereQuery = " WHERE t.date BETWEEN @from AND @to "; - return whereQuery; - } - - private static string AddSortBy(string sortby, string order) - { - List validSorting = ["f_name", "l_name", "mail", "time", "date", "user", "project"]; - if (!validSorting.Contains(sortby)) - { - throw new Exception("Incorrect sorting value"); - } - string orderQuery = " ORDER BY " + sortby + " " + order; - return orderQuery; - } - - private static List ExtractDataFromDB(MySqlCommand cmd) - { - using MySqlConnection conn = new(connectionString); - conn.Open(); - cmd.Connection = conn; - // execute query and read results - MySqlDataReader reader = cmd.ExecuteReader(); - - List entries = []; - while (reader.Read()) - { - entries.Add( - new Log - { - FName = reader["f_name"], - LName = reader["l_name"], - User = reader["user"], - Date = reader["date"], - Name = reader["name"], - Time = reader["time"], - Mail = reader["mail"], - } - ); - } - return entries; - } - - public static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response) - { - try - { - // extract data from url - var queryString = request.QueryString; - string? from = queryString["from"] ?? ""; - string? to = queryString["to"] ?? ""; - string? sortby = queryString["sortby"] ?? ""; - string? offset = queryString["offset"] ?? ""; - string? order = queryString["order"] ?? ""; - order = order == "true" ? "ASC" : "DESC"; - // SQL - MySqlCommand cmd = new(ConstructQuery(from, to, order, offset, sortby)); - cmd.Parameters.AddWithValue("@from", from); - cmd.Parameters.AddWithValue("@to", to); - var entries = ExtractDataFromDB(cmd); - - // serialize JSON - string jsonResponse = JsonConvert.SerializeObject(entries); - SendSuccess(response, jsonResponse); - } - catch (Exception ex) - { - SendError(response, ex); - } - } -} diff --git a/backendCS/routes/Gettopten.cs b/backendCS/routes/Gettopten.cs deleted file mode 100644 index 7c1453a..0000000 --- a/backendCS/routes/Gettopten.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.Net; -using MySql.Data.MySqlClient; -using Newtonsoft.Json; - -namespace TimelogBackend; - -public class TopTen -{ - public object? User { get; set; } - public object? Date { get; set; } - public object? Project { get; set; } - public object? FName { get; set; } - public object? LName { get; set; } - public object? Name { get; set; } - public object? TotalTime { get; set; } -} - -public class Gettopten : Route -{ - private static List ExtractDataFromDB(MySqlCommand cmd) - { - using MySqlConnection conn = new(connectionString); - cmd.Connection = conn; - conn.Open(); - // Execute the query and read the results - MySqlDataReader reader = cmd.ExecuteReader(); - List entries = []; - while (reader.Read()) - { - entries.Add( - new TopTen - { - User = reader["user"], - Date = reader["date"], - Project = reader["project"], - FName = reader["f_name"], - LName = reader["l_name"], - Name = reader["name"], - TotalTime = reader["total_time"], - } - ); - } - return entries; - } - - private static void ValidateQueryStrings(string from, string to, string filterBy) - { - if (!string.IsNullOrEmpty(to) && !string.IsNullOrEmpty(from)) - { - ValidateDate(to); - ValidateDate(from); - } - else - { - throw new Exception("Empty date format"); - } - if (string.IsNullOrEmpty(filterBy)) - { - throw new Exception("Empty filterby"); - } - if (filterBy != "user" && filterBy != "project") - { - throw new Exception("Incorrect filterby"); - } - } - - public static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response) - { - try - { - var queryString = request.QueryString; - string? from = queryString["from"] ?? ""; - string? to = queryString["to"] ?? ""; - string? filterBy = queryString["filterBy"] ?? ""; - ValidateQueryStrings(from, to, filterBy); - string query = - @"SELECT t.user,t.date,t.project,u.f_name,u.l_name,p.name,SUM(t.time) as total_time - FROM Timelog t - INNER JOIN Project p ON p.id=t.project - INNER JOIN User u ON u.id=t.user - WHERE t.date BETWEEN @from AND @to - GROUP BY " - + filterBy - + " ORDER BY total_time DESC LIMIT 10;"; - MySqlCommand cmd = new(query); - cmd.Parameters.AddWithValue("@from", from); - cmd.Parameters.AddWithValue("@to", to); - - var entries = ExtractDataFromDB(cmd); - string jsonResponse = JsonConvert.SerializeObject(entries); - SendSuccess(response, jsonResponse); - } - catch (Exception ex) - { - SendError(response, ex); - } - } -} diff --git a/backendCS/routes/Getuser.cs b/backendCS/routes/Getuser.cs deleted file mode 100644 index 498a4d3..0000000 --- a/backendCS/routes/Getuser.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Dynamic; -using System.Net; -using MySql.Data.MySqlClient; -using Newtonsoft.Json; - -namespace TimelogBackend; - -public class Getuser : Route -{ - private static dynamic ExtractDataFromDB(MySqlCommand cmd) - { - using MySqlConnection conn = new(connectionString); - conn.Open(); - cmd.Connection = conn; - // execute query and read results - MySqlDataReader reader = cmd.ExecuteReader(); - dynamic expando = new ExpandoObject(); - while (reader.Read()) - { - ((IDictionary)expando)[reader["name"].ToString()] = reader[ - "SUM(t.time)" - ]; - } - return expando; - } - - public static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response) - { - try - { - var queryString = request.QueryString; - string? userid = queryString["userid"]; - if (string.IsNullOrEmpty(userid)) - { - throw new Exception("Missing userid"); - } - // prepare SQL query - string query = - @"SELECT p.name, SUM(t.time) - FROM Timelog t - INNER JOIN Project p ON p.id=t.project - INNER JOIN User u ON u.id=t.user - WHERE User = @userid - GROUP BY name;"; - MySqlCommand cmd = new(query); - cmd.Parameters.AddWithValue("@userid", userid); - - var expando = ExtractDataFromDB(cmd); - // serialize JSON - string jsonResponse = JsonConvert.SerializeObject(expando); - // prepare response - SendSuccess(response, jsonResponse); - } - catch (Exception ex) - { - SendError(response, ex); - } - } -} diff --git a/backendCS/routes/Login.cs b/backendCS/routes/Login.cs deleted file mode 100644 index 45347b6..0000000 --- a/backendCS/routes/Login.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System.IdentityModel.Tokens.Jwt; -using System.Net; -using System.Security.Claims; -using System.Security.Cryptography; -using System.Text; -using Microsoft.IdentityModel.Tokens; -using MySql.Data.MySqlClient; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace TimelogBackend; - -public class Login : Route -{ - private static readonly string secretKey = - "stronk-key-much-sercret-much-more-stronk-stronk-key-much-sercret-much-more-stronk"; - - public static string GenerateToken(string user) - { - var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)); - var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); - - var token = new JwtSecurityToken( - issuer: "TimeLogServer", - audience: "TimeLogWebsite", - claims: [new Claim("user", user)], - expires: DateTime.Now.AddHours(2), - signingCredentials: creds - ); - - return new JwtSecurityTokenHandler().WriteToken(token); - } - - public static bool VerifyPassword(string enteredPassword, string storedHash) - { - byte[] hashBytes = Convert.FromBase64String(storedHash); - - byte[] salt = new byte[16]; - Array.Copy(hashBytes, 0, salt, 0, 16); - - using var pbkdf2 = new Rfc2898DeriveBytes( - enteredPassword, - salt, - 10000, - HashAlgorithmName.SHA256 - ); - byte[] newHash = pbkdf2.GetBytes(32); - - for (int i = 0; i < 32; i++) - { - if (newHash[i] != hashBytes[i + 16]) - return false; - } - return true; - } - - private static string ExtractDataFromDB(MySqlCommand cmd, string password) - { - using MySqlConnection conn = new(connectionString); - cmd.Connection = conn; - conn.Open(); - // execute query and read results - MySqlDataReader reader = cmd.ExecuteReader(); - string? userId = ""; - string? hashedPass = ""; - while (reader.Read()) - { - userId = Convert.ToString(reader["id"]); - hashedPass = reader.GetString("password"); - } - // check username - if (string.IsNullOrEmpty(userId)) - { - throw new Exception("Invalid Username or Password"); - } - //check password - if ( - string.IsNullOrEmpty(password) - || string.IsNullOrEmpty(hashedPass) - || !VerifyPassword(password, hashedPass) - ) - { - throw new Exception("Invalid Username or Password"); - } - return userId; - } - - public static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response) - { - try - { - // extract data from body - string body; - using (StreamReader bodyReader = new(request.InputStream, request.ContentEncoding)) - { - body = bodyReader.ReadToEnd(); - } - JObject jsonObject = JObject.Parse(body); - string mail = jsonObject["mail"]?.ToString() ?? ""; - string password = jsonObject["password"]?.ToString() ?? ""; - // prepare SQL query - string query = - @"SELECT u.id, password FROM User u - INNER JOIN Password p ON p.user=u.id - WHERE mail=@mail;"; - MySqlCommand cmd = new(query); - cmd.Parameters.AddWithValue("@mail", mail); - - var userId = ExtractDataFromDB(cmd, password); - string? jsonResponse = JsonConvert.SerializeObject(GenerateToken(userId)); - // prepare response - SendSuccess(response, jsonResponse); - } - catch (Exception ex) - { - SendError(response, ex); - } - } -} diff --git a/backendCS/routes/Register.cs b/backendCS/routes/Register.cs deleted file mode 100644 index 0157cd8..0000000 --- a/backendCS/routes/Register.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.Net; -using System.Security.Cryptography; -using MySql.Data.MySqlClient; -using Newtonsoft.Json.Linq; - -namespace TimelogBackend; - -public class Register : Route -{ - private static string HashPassword(string password) - { - byte[] salt = new byte[16]; - RandomNumberGenerator.Fill(salt); - - using var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000, HashAlgorithmName.SHA256); - byte[] hash = pbkdf2.GetBytes(32); - - byte[] hashBytes = new byte[48]; // 16 (salt) + 32 (hash) - Array.Copy(salt, 0, hashBytes, 0, 16); - Array.Copy(hash, 0, hashBytes, 16, 32); - - return Convert.ToBase64String(hashBytes); - } - - public static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response) - { - MySqlTransaction? transaction = null; - try - { - // extract parameters from req body - string body; - using (StreamReader bodyReader = new(request.InputStream, request.ContentEncoding)) - { - body = bodyReader.ReadToEnd(); - } - JObject jsonObject = JObject.Parse(body); - string f_name = jsonObject["f_name"]?.ToString() ?? ""; - string l_name = jsonObject["l_name"]?.ToString() ?? ""; - string password = jsonObject["password"]?.ToString() ?? ""; - string mail = jsonObject["mail"]?.ToString() ?? ""; - - // validate parameters - if ( - string.IsNullOrEmpty(f_name) - || f_name.Length > 30 - || f_name.Length < 2 - || string.IsNullOrEmpty(l_name) - || l_name.Length > 30 - || l_name.Length < 2 - || string.IsNullOrEmpty(mail) - || mail.Length > 50 - || mail.Length < 6 - || string.IsNullOrEmpty(password) - || password.Length > 30 - || password.Length < 10 - ) - { - throw new Exception("Wrong parameters"); - } - // TODO Validate dupes of email - string query = "INSERT INTO User(f_name,l_name,mail) VALUES(@f_name,@l_name,@mail)"; - MySqlCommand cmd = new(query); - cmd.Parameters.AddWithValue("@f_name", f_name); - cmd.Parameters.AddWithValue("@l_name", l_name); - cmd.Parameters.AddWithValue("@mail", mail); - - using MySqlConnection conn = new(connectionString); - conn.Open(); - transaction = conn.BeginTransaction(); - cmd.Connection = conn; - cmd.ExecuteNonQuery(); - - // Get user ID - cmd.CommandText = "SELECT id FROM User WHERE mail=@mail;"; - MySqlDataReader reader = cmd.ExecuteReader(); - reader.Read(); - var id = reader["id"]; - reader.Close(); - - // Insert into password - cmd.CommandText = "INSERT INTO Password(user,password) VALUES(@id,@password)"; - cmd.Parameters.AddWithValue("@password", HashPassword(password)); - cmd.Parameters.AddWithValue("@id", id); - cmd.ExecuteNonQuery(); - transaction.Commit(); - - SendSuccess(response); - } - catch (Exception ex) - { - transaction?.Rollback(); - SendError(response, ex); - } - } -} diff --git a/backendCS/routes/Reset.cs b/backendCS/routes/Reset.cs deleted file mode 100644 index 5c9e536..0000000 --- a/backendCS/routes/Reset.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Net; -using MySql.Data.MySqlClient; - -namespace TimelogBackend; - -public class Reset : Route -{ - public static void HandleRequest(HttpListenerResponse response) - { - try - { - // prepare SQL query - MySqlCommand cmd = new() { CommandText = "CALL InitDB" }; - using (MySqlConnection conn = new MySqlConnection(connectionString)) - { - cmd.Connection = conn; - // open connection - conn.Open(); - // execute query - cmd.ExecuteNonQuery(); - // set up and send response - SendSuccess(response); - } - } - catch (Exception ex) - { - SendError(response, ex); - } - } -} diff --git a/backendCS/test.sh b/backendCS/test.sh deleted file mode 100755 index 147c453..0000000 --- a/backendCS/test.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -url="localhost:5000/" # Replace with your URL - -# Loop to send 1000 requests -for i in {1..10000} -do - curl -s $url > /dev/null & # Send the request in the background -done - -# Wait for all background processes to finish -wait -echo "1000 requests sent!"