From 05dedc7392e8d8e9143aed5382d40e84a3a1d9fb Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Mon, 3 Jun 2024 06:25:07 -0500 Subject: [PATCH 01/39] admin scan --- src/app.ts | 2 ++ src/services/admin/admin-router.ts | 40 ++++++++++++++++++++++++++++++ src/services/admin/admin-utils.ts | 27 ++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/services/admin/admin-router.ts create mode 100644 src/services/admin/admin-utils.ts diff --git a/src/app.ts b/src/app.ts index 6da05cb..4547c1b 100644 --- a/src/app.ts +++ b/src/app.ts @@ -10,6 +10,7 @@ import bodyParser from "body-parser"; import errorHandler from "./middleware/error-handler"; import attendeeRouter from "./services/attendees/attendee-router"; +import adminRouter from "./services/admin/admin-router"; import authRouter from "./services/auth/auth-router"; import eventsRouter from "./services/events/events-router"; import notificationsRouter from "./services/notifications/notifications-router"; @@ -34,6 +35,7 @@ app.use("/", bodyParser.json()); // API routes app.use("/attendee", attendeeRouter); +app.use("/admin", adminRouter); app.use("/auth", authRouter); app.use("/events", eventsRouter); app.use("/notifications", notificationsRouter); diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts new file mode 100644 index 0000000..13bdf20 --- /dev/null +++ b/src/services/admin/admin-router.ts @@ -0,0 +1,40 @@ +import { Router } from "express"; +import { StatusCodes } from "http-status-codes"; +import { Database } from "../../database"; +import RoleChecker from "../../middleware/role-checker"; +import { Role } from "../auth/auth-models"; +import dotenv from "dotenv"; +import { validateQrHash } from "./admin-utils"; + +dotenv.config(); + +const adminRouter = Router(); + +adminRouter.post( + "/scan", + RoleChecker([Role.Enum.ADMIN]), + async (req, res, next) => { + try { + const { qrCode } = req.body; + const { userId, expTime } = validateQrHash(qrCode); + + if (Date.now() / 1000 > expTime) { + return res.status(StatusCodes.UNAUTHORIZED).json({ error: "QR code has expired" }); + } + + const user = await Database.ATTENDEES.findOne({ userId }); + + if (!user) { + return res + .status(StatusCodes.NOT_FOUND) + .json({ error: "UserNotFound" }); + } + + return res.status(StatusCodes.OK).json(user); + } catch (error) { + next(error); + } + } +); + +export default adminRouter; \ No newline at end of file diff --git a/src/services/admin/admin-utils.ts b/src/services/admin/admin-utils.ts new file mode 100644 index 0000000..6a37510 --- /dev/null +++ b/src/services/admin/admin-utils.ts @@ -0,0 +1,27 @@ +import crypto from "crypto"; +import { Config } from "../../config"; + +export function generateQrHash(userId: string, expTime: number) { + let hashStr = userId + "#" + expTime; + const hashIterations = Config.QR_HASH_ITERATIONS; + const hashSecret = Config.QR_HASH_SECRET; + + const hmac = crypto.createHmac("sha256", hashSecret); + hashStr = hmac.update(hashStr).digest("hex"); + + for (let i = 0; i < hashIterations; i++) { + const hash = crypto.createHash("sha256"); + hashStr = hash.update(hashSecret + "#" + hashStr).digest("hex"); + } + + return `${hashStr}#${expTime}#${userId}`; +} + +export function validateQrHash(qrCode: string) { + const [hashStr, expTime, userId] = qrCode.split('#'); + const generatedHash = generateQrHash(userId, parseInt(expTime)); + if (generatedHash.split('#')[0] !== hashStr) { + throw new Error("Invalid QR code"); + } + return { userId, expTime: parseInt(expTime) }; +} \ No newline at end of file From 47cc5975bf803e3ecdc03122ed225df75da9f13b Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Tue, 4 Jun 2024 22:42:06 -0500 Subject: [PATCH 02/39] finished admin-scan --- src/services/admin/admin-router.ts | 14 +- src/services/admin/admin-utils.ts | 14 +- yarn.lock | 257 +++++++++++++++++++++-------- 3 files changed, 205 insertions(+), 80 deletions(-) diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 13bdf20..982ba6d 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -11,15 +11,23 @@ dotenv.config(); const adminRouter = Router(); adminRouter.post( - "/scan", + "/scan/", RoleChecker([Role.Enum.ADMIN]), async (req, res, next) => { try { const { qrCode } = req.body; + if (!qrCode) { + console.log("made it to if"); + return res + .status(StatusCodes.BAD_REQUEST) + .json({ error: "QR code is required" }); + } const { userId, expTime } = validateQrHash(qrCode); if (Date.now() / 1000 > expTime) { - return res.status(StatusCodes.UNAUTHORIZED).json({ error: "QR code has expired" }); + return res + .status(StatusCodes.UNAUTHORIZED) + .json({ error: "QR code has expired" }); } const user = await Database.ATTENDEES.findOne({ userId }); @@ -37,4 +45,4 @@ adminRouter.post( } ); -export default adminRouter; \ No newline at end of file +export default adminRouter; diff --git a/src/services/admin/admin-utils.ts b/src/services/admin/admin-utils.ts index 6a37510..6af110b 100644 --- a/src/services/admin/admin-utils.ts +++ b/src/services/admin/admin-utils.ts @@ -18,10 +18,14 @@ export function generateQrHash(userId: string, expTime: number) { } export function validateQrHash(qrCode: string) { - const [hashStr, expTime, userId] = qrCode.split('#'); - const generatedHash = generateQrHash(userId, parseInt(expTime)); - if (generatedHash.split('#')[0] !== hashStr) { + const parts = qrCode.split("#"); + const userId = parts[2]; + const expTime = parseInt(parts[1]); + const generatedHash = generateQrHash(userId, expTime); + + if (generatedHash.split("#")[0] !== parts[0]) { throw new Error("Invalid QR code"); } - return { userId, expTime: parseInt(expTime) }; -} \ No newline at end of file + + return { userId, expTime }; +} diff --git a/yarn.lock b/yarn.lock index b032d0b..1cb68ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -59,7 +59,7 @@ "@aws-sdk/util-utf8-browser" "^3.0.0" tslib "^1.11.1" -"@aws-crypto/sha256-js@^3.0.0", "@aws-crypto/sha256-js@3.0.0": +"@aws-crypto/sha256-js@3.0.0", "@aws-crypto/sha256-js@^3.0.0": version "3.0.0" resolved "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz" integrity sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ== @@ -84,7 +84,7 @@ "@aws-sdk/util-utf8-browser" "^3.0.0" tslib "^1.11.1" -"@aws-sdk/client-s3@^3.496.0", "@aws-sdk/client-s3@3.556.0": +"@aws-sdk/client-s3@3.556.0", "@aws-sdk/client-s3@^3.496.0": version "3.556.0" resolved "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.556.0.tgz" integrity sha512-6WF9Kuzz1/8zqX8hKBpqj9+FYwQ5uTsVcOKpTW94AMX2qtIeVRlwlnNnYyywWo61yqD3g59CMNHcqSsaqAwglg== @@ -335,7 +335,7 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-node@^3.556.0", "@aws-sdk/credential-provider-node@3.556.0": +"@aws-sdk/credential-provider-node@3.556.0": version "3.556.0" resolved "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.556.0.tgz" integrity sha512-s1xVtKjyGc60O8qcNIzS1X3H+pWEwEfZ7TgNznVDNyuXvLrlNWiAcigPWGl2aAkc8tGcsSG0Qpyw2KYC939LFg== @@ -576,7 +576,7 @@ "@smithy/types" "^2.12.0" tslib "^2.6.2" -"@aws-sdk/types@^3.222.0", "@aws-sdk/types@3.535.0": +"@aws-sdk/types@3.535.0", "@aws-sdk/types@^3.222.0": version "3.535.0" resolved "https://registry.npmjs.org/@aws-sdk/types/-/types-3.535.0.tgz" integrity sha512-aY4MYfduNj+sRR37U7XxYR8wemfbKP6lx00ze2M2uubn7mZotuVrWYAafbMSXrdEMSToE5JDhr28vArSOoLcSg== @@ -668,6 +668,116 @@ dependencies: regenerator-runtime "^0.14.0" +"@esbuild/aix-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" + integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== + +"@esbuild/android-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" + integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== + +"@esbuild/android-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" + integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== + +"@esbuild/android-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" + integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== + +"@esbuild/darwin-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" + integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== + +"@esbuild/darwin-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" + integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== + +"@esbuild/freebsd-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" + integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== + +"@esbuild/freebsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" + integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== + +"@esbuild/linux-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" + integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== + +"@esbuild/linux-arm@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" + integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== + +"@esbuild/linux-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" + integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== + +"@esbuild/linux-loong64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" + integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== + +"@esbuild/linux-mips64el@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" + integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== + +"@esbuild/linux-ppc64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" + integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== + +"@esbuild/linux-riscv64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" + integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== + +"@esbuild/linux-s390x@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" + integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== + +"@esbuild/linux-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" + integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== + +"@esbuild/netbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" + integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== + +"@esbuild/openbsd-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" + integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== + +"@esbuild/sunos-x64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" + integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== + +"@esbuild/win32-arm64@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" + integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== + +"@esbuild/win32-ia32@0.19.12": + version "0.19.12" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" + integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== + "@esbuild/win32-x64@0.19.12": version "0.19.12" resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz" @@ -734,7 +844,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1418,7 +1528,7 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha", "@typescript-eslint/parser@^6.4.0": +"@typescript-eslint/parser@^6.4.0": version "6.21.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz" integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== @@ -1505,7 +1615,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0: +acorn@^8.9.0: version "8.11.3" resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== @@ -1701,7 +1811,7 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== -body-parser@^1.20.2, body-parser@1.20.2: +body-parser@1.20.2, body-parser@^1.20.2: version "1.20.2" resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== @@ -1938,33 +2048,26 @@ data-view-byte-offset@^1.0.0: es-errors "^1.3.0" is-data-view "^1.0.1" -debug@^2.6.9: +debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@4.x: +debug@4.x, debug@^4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: - ms "2.0.0" + ms "^2.1.1" deep-is@^0.1.3: version "0.1.4" @@ -1994,7 +2097,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@~2.0.0, depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -2025,11 +2128,16 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dotenv@*, dotenv@^16.4.5: +dotenv@*: version "16.4.5" resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== +dotenv@^16.4.5: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + ecdsa-sig-formatter@1.0.11: version "1.0.11" resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" @@ -2221,7 +2329,7 @@ eslint-config-airbnb@19.0.4: object.assign "^4.1.2" object.entries "^1.1.5" -eslint-config-prettier@*, eslint-config-prettier@^9.1.0: +eslint-config-prettier@^9.1.0: version "9.1.0" resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz" integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== @@ -2264,7 +2372,7 @@ eslint-plugin-es-x@^7.5.0: "@eslint-community/regexpp" "^4.6.0" eslint-compat-utils "^0.5.0" -eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.25.3, eslint-plugin-import@2.25.3: +eslint-plugin-import@2.25.3: version "2.25.3" resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz" integrity sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg== @@ -2283,7 +2391,7 @@ eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.25.3, eslint-plugin-import resolve "^1.20.0" tsconfig-paths "^3.11.0" -eslint-plugin-jsx-a11y@^6.5.1, eslint-plugin-jsx-a11y@6.5.1: +eslint-plugin-jsx-a11y@6.5.1: version "6.5.1" resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz" integrity sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g== @@ -2331,12 +2439,12 @@ eslint-plugin-promise@^6.0.0: resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz" integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== -eslint-plugin-react-hooks@^4.3.0, eslint-plugin-react-hooks@4.3.0: +eslint-plugin-react-hooks@4.3.0: version "4.3.0" resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz" integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA== -eslint-plugin-react@^7.28.0, eslint-plugin-react@7.28.0: +eslint-plugin-react@7.28.0: version "7.28.0" resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz" integrity sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw== @@ -2381,7 +2489,7 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", "eslint@^7.32.0 || ^8.2.0", eslint@^8.0.1, eslint@>=5, eslint@>=6.0.0, eslint@>=7.0.0, eslint@>=8, eslint@>=8.0.0, eslint@8.2.0: +eslint@8.2.0: version "8.2.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.2.0.tgz" integrity sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw== @@ -2473,7 +2581,7 @@ express-rate-limit@*, express-rate-limit@^6.0.0: resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.11.2.tgz" integrity sha512-a7uwwfNTh1U60ssiIkuLFWHt4hAC5yxlLGU2VP0X4YNlyEDZAqF4tK3GD3NSitVBrCQmQ0++0uOyFOgC2y4DDw== -"express@^4 || ^5", express@^4.19.1: +express@^4.19.1: version "4.19.2" resolved "https://registry.npmjs.org/express/-/express-4.19.2.tgz" integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== @@ -2632,6 +2740,11 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -2822,7 +2935,7 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.4, ieee754@1.1.13: +ieee754@1.1.13, ieee754@^1.1.4: version "1.1.13" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== @@ -2863,7 +2976,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.3, inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3265,13 +3378,6 @@ mime@1.6.0: resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - minimatch@9.0.3: version "9.0.3" resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" @@ -3279,6 +3385,13 @@ minimatch@9.0.3: dependencies: brace-expansion "^2.0.1" +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -3337,11 +3450,6 @@ mquery@5.0.0: dependencies: debug "4.x" -ms@^2.1.1, ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" @@ -3352,6 +3460,11 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" @@ -3457,13 +3570,6 @@ object.values@^1.1.5, object.values@^1.1.6: define-properties "^1.2.1" es-object-atoms "^1.0.0" -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" - integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== - dependencies: - ee-first "1.1.1" - on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" @@ -3471,6 +3577,13 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + on-headers@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" @@ -3591,7 +3704,7 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@>=3.0.0, prettier@3.2.5: +prettier@3.2.5: version "3.2.5" resolved "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== @@ -3628,16 +3741,16 @@ pstree.remy@^1.1.8: resolved "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz" integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== -punycode@^2.1.0, punycode@^2.3.0: - version "2.3.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - punycode@1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== +punycode@^2.1.0, punycode@^2.3.0: + version "2.3.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + qs@6.11.0: version "6.11.0" resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" @@ -3759,16 +3872,16 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.0.1, safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@5.2.1, safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-regex-test@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz" @@ -3783,7 +3896,7 @@ safe-regex-test@^1.0.3: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@>=0.6.0, sax@1.2.1: +sax@1.2.1, sax@>=0.6.0: version "1.2.1" resolved "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz" integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== @@ -4132,7 +4245,7 @@ typed-array-length@^1.0.6: is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" -typescript@*, typescript@^5.3.2, typescript@>=4.2.0: +typescript@^5.3.2: version "5.4.5" resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz" integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== @@ -4162,7 +4275,7 @@ undici-types@~5.26.4: resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -unpipe@~1.0.0, unpipe@1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -4193,21 +4306,21 @@ util@^0.12.4: is-typed-array "^1.1.3" which-typed-array "^1.1.2" -utils-merge@^1.0.1, utils-merge@1.0.1, utils-merge@1.x.x: +utils-merge@1.0.1, utils-merge@1.x.x, utils-merge@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^9.0.1: - version "9.0.1" - resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - uuid@8.0.0: version "8.0.0" resolved "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz" integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== +uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-compile-cache@^2.0.3: version "2.4.0" resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz" From f23249b3d3839b423cd8fe30b62fc1f7f40e38e6 Mon Sep 17 00:00:00 2001 From: sdagg9 <113925197+sdagg9@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:11:20 -0500 Subject: [PATCH 03/39] Update src/services/admin/admin-router.ts Co-authored-by: Divya Koya <90989518+divyack2@users.noreply.github.com> --- src/services/admin/admin-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 982ba6d..1650d1a 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -17,7 +17,7 @@ adminRouter.post( try { const { qrCode } = req.body; if (!qrCode) { - console.log("made it to if"); + return res .status(StatusCodes.BAD_REQUEST) .json({ error: "QR code is required" }); From b43555f78daeb7e79b52a78af02598059f394acf Mon Sep 17 00:00:00 2001 From: sdagg9 <113925197+sdagg9@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:12:05 -0500 Subject: [PATCH 04/39] Update src/services/admin/admin-router.ts Co-authored-by: Aydan Pirani --- src/services/admin/admin-router.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 1650d1a..7e3360d 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -6,7 +6,6 @@ import { Role } from "../auth/auth-models"; import dotenv from "dotenv"; import { validateQrHash } from "./admin-utils"; -dotenv.config(); const adminRouter = Router(); From 97b2875dd24521541552654624577eb30203249b Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Mon, 10 Jun 2024 12:34:57 -0500 Subject: [PATCH 05/39] removed admin-util --- src/services/admin/admin-router.ts | 2 +- src/services/admin/admin-utils.ts | 31 ----------------------- src/services/attendees/attendees-utils.ts | 13 ++++++++++ 3 files changed, 14 insertions(+), 32 deletions(-) delete mode 100644 src/services/admin/admin-utils.ts diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 7e3360d..1e0a06c 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -4,7 +4,7 @@ import { Database } from "../../database"; import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; import dotenv from "dotenv"; -import { validateQrHash } from "./admin-utils"; +import { validateQrHash } from "../attendees/attendees-utils"; const adminRouter = Router(); diff --git a/src/services/admin/admin-utils.ts b/src/services/admin/admin-utils.ts deleted file mode 100644 index 6af110b..0000000 --- a/src/services/admin/admin-utils.ts +++ /dev/null @@ -1,31 +0,0 @@ -import crypto from "crypto"; -import { Config } from "../../config"; - -export function generateQrHash(userId: string, expTime: number) { - let hashStr = userId + "#" + expTime; - const hashIterations = Config.QR_HASH_ITERATIONS; - const hashSecret = Config.QR_HASH_SECRET; - - const hmac = crypto.createHmac("sha256", hashSecret); - hashStr = hmac.update(hashStr).digest("hex"); - - for (let i = 0; i < hashIterations; i++) { - const hash = crypto.createHash("sha256"); - hashStr = hash.update(hashSecret + "#" + hashStr).digest("hex"); - } - - return `${hashStr}#${expTime}#${userId}`; -} - -export function validateQrHash(qrCode: string) { - const parts = qrCode.split("#"); - const userId = parts[2]; - const expTime = parseInt(parts[1]); - const generatedHash = generateQrHash(userId, expTime); - - if (generatedHash.split("#")[0] !== parts[0]) { - throw new Error("Invalid QR code"); - } - - return { userId, expTime }; -} diff --git a/src/services/attendees/attendees-utils.ts b/src/services/attendees/attendees-utils.ts index 06a4a5a..44169ad 100644 --- a/src/services/attendees/attendees-utils.ts +++ b/src/services/attendees/attendees-utils.ts @@ -16,3 +16,16 @@ export function generateQrHash(userId: string, expTime: number) { return `${hashStr}#${expTime}#${userId}`; } + +export function validateQrHash(qrCode: string) { + const parts = qrCode.split("#"); + const userId = parts[2]; + const expTime = parseInt(parts[1]); + const generatedHash = generateQrHash(userId, expTime); + + if (generatedHash.split("#")[0] !== parts[0]) { + throw new Error("Invalid QR code"); + } + + return { userId, expTime }; +} \ No newline at end of file From afc32f35fd2ed8117c66988550842f983c5c4000 Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Mon, 10 Jun 2024 12:38:12 -0500 Subject: [PATCH 06/39] removed admin-util --- src/services/admin/admin-router.ts | 4 +--- src/services/attendees/attendees-utils.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 1e0a06c..681a9fa 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -3,10 +3,9 @@ import { StatusCodes } from "http-status-codes"; import { Database } from "../../database"; import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; -import dotenv from "dotenv"; +// import dotenv from "dotenv"; import { validateQrHash } from "../attendees/attendees-utils"; - const adminRouter = Router(); adminRouter.post( @@ -16,7 +15,6 @@ adminRouter.post( try { const { qrCode } = req.body; if (!qrCode) { - return res .status(StatusCodes.BAD_REQUEST) .json({ error: "QR code is required" }); diff --git a/src/services/attendees/attendees-utils.ts b/src/services/attendees/attendees-utils.ts index 44169ad..6af110b 100644 --- a/src/services/attendees/attendees-utils.ts +++ b/src/services/attendees/attendees-utils.ts @@ -28,4 +28,4 @@ export function validateQrHash(qrCode: string) { } return { userId, expTime }; -} \ No newline at end of file +} From dc5666ba97a1122c922c31c32a6a36d9c3cc6c5e Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Mon, 10 Jun 2024 18:56:21 -0500 Subject: [PATCH 07/39] validator --- src/services/admin/admin-schema | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/services/admin/admin-schema diff --git a/src/services/admin/admin-schema b/src/services/admin/admin-schema new file mode 100644 index 0000000..9d24197 --- /dev/null +++ b/src/services/admin/admin-schema @@ -0,0 +1,6 @@ +import { z } from "zod"; + +const ScanValidator = z.object({ + eventId: z.string(), + qrCode: z.string(), +}); \ No newline at end of file From f63c561e194881a9641b755ac5e2a90f47cece6e Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Mon, 10 Jun 2024 19:01:17 -0500 Subject: [PATCH 08/39] added validator for event --- src/services/admin/admin-router.ts | 3 ++- src/services/admin/admin-schema | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 src/services/admin/admin-schema diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 681a9fa..e890bfc 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -1,5 +1,6 @@ import { Router } from "express"; import { StatusCodes } from "http-status-codes"; +import { ScanValidator } from "./admin-schema"; import { Database } from "../../database"; import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; @@ -13,7 +14,7 @@ adminRouter.post( RoleChecker([Role.Enum.ADMIN]), async (req, res, next) => { try { - const { qrCode } = req.body; + const { eventId, qrCode } = ScanValidator.parse(req.body); if (!qrCode) { return res .status(StatusCodes.BAD_REQUEST) diff --git a/src/services/admin/admin-schema b/src/services/admin/admin-schema deleted file mode 100644 index 9d24197..0000000 --- a/src/services/admin/admin-schema +++ /dev/null @@ -1,6 +0,0 @@ -import { z } from "zod"; - -const ScanValidator = z.object({ - eventId: z.string(), - qrCode: z.string(), -}); \ No newline at end of file From c9691a5cf37fa7317c773aa175ee98a4c8e1f57e Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Mon, 10 Jun 2024 19:08:19 -0500 Subject: [PATCH 09/39] tested on postman --- src/services/admin/admin-router.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index e890bfc..06af25e 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -15,6 +15,8 @@ adminRouter.post( async (req, res, next) => { try { const { eventId, qrCode } = ScanValidator.parse(req.body); + console.log("Event ID:", eventId); + if (!qrCode) { return res .status(StatusCodes.BAD_REQUEST) From 7d1c3ace2d1ec4d08a2652d3b665ae7990544b6c Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Mon, 10 Jun 2024 19:09:59 -0500 Subject: [PATCH 10/39] lint --- src/services/admin/admin-schema.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/services/admin/admin-schema.ts diff --git a/src/services/admin/admin-schema.ts b/src/services/admin/admin-schema.ts new file mode 100644 index 0000000..c0b7c0a --- /dev/null +++ b/src/services/admin/admin-schema.ts @@ -0,0 +1,8 @@ +import { z } from "zod"; + +const ScanValidator = z.object({ + eventId: z.string(), + qrCode: z.string(), +}); + +export { ScanValidator }; From 2e77f74cbfb5e4f31a7fb21feb55864b3eea2b7b Mon Sep 17 00:00:00 2001 From: sdagg9 <113925197+sdagg9@users.noreply.github.com> Date: Thu, 13 Jun 2024 09:19:38 -0500 Subject: [PATCH 11/39] Update src/services/admin/admin-router.ts Co-authored-by: Aydan Pirani --- src/services/admin/admin-router.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 06af25e..76b5ea3 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -17,11 +17,6 @@ adminRouter.post( const { eventId, qrCode } = ScanValidator.parse(req.body); console.log("Event ID:", eventId); - if (!qrCode) { - return res - .status(StatusCodes.BAD_REQUEST) - .json({ error: "QR code is required" }); - } const { userId, expTime } = validateQrHash(qrCode); if (Date.now() / 1000 > expTime) { From ae4447c19be7d8e9b122945492a7366153981c37 Mon Sep 17 00:00:00 2001 From: Alex Yang <32620988+DatProJack@users.noreply.github.com> Date: Wed, 3 Jul 2024 01:41:28 -0400 Subject: [PATCH 12/39] fixed install_dependencies.sh --- scripts/install_dependencies.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/install_dependencies.sh b/scripts/install_dependencies.sh index 11f0644..a2d1598 100644 --- a/scripts/install_dependencies.sh +++ b/scripts/install_dependencies.sh @@ -2,13 +2,11 @@ cd /home/ubuntu/rp-api sudo yarn -sudo pm2 describe appname 2>&1 /dev/null + +sudo pm2 describe RP_API 2>&1 /dev/null RUNNING=$? -if [ "${RUNNING}" -eq 0 ]; then +if [ "${RUNNING}" -eq 1 ]; then sudo pm2 start build/app.js --name RP_API -i 2 --wait-ready --listen-timeout 10000 fi; - - - From bda01be013c1c3539811447865a33b7d8e77a56f Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Fri, 5 Jul 2024 13:08:02 -0700 Subject: [PATCH 13/39] clean up resume service --- src/services/s3/s3-router.ts | 78 ++++++++++++++---------------------- src/services/s3/s3-utils.ts | 32 +++++++++++++++ 2 files changed, 62 insertions(+), 48 deletions(-) create mode 100644 src/services/s3/s3-utils.ts diff --git a/src/services/s3/s3-router.ts b/src/services/s3/s3-router.ts index 2fd57f0..52f631d 100644 --- a/src/services/s3/s3-router.ts +++ b/src/services/s3/s3-router.ts @@ -1,13 +1,11 @@ -import { Request, Response, Router } from "express"; +import { Router } from "express"; +import { StatusCodes } from "http-status-codes"; import RoleChecker from "../../middleware/role-checker"; import { s3ClientMiddleware } from "../../middleware/s3"; -import { StatusCodes } from "http-status-codes"; -import { Config } from "../../config"; import { Role } from "../auth/auth-models"; -import { GetObjectCommand, S3 } from "@aws-sdk/client-s3"; -import { createPresignedPost } from "@aws-sdk/s3-presigned-post"; -import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; +import { S3 } from "@aws-sdk/client-s3"; +import { getResumeUrl, postResumeUrl } from "./s3-utils"; const s3Router: Router = Router(); @@ -15,70 +13,54 @@ s3Router.get( "/upload/", RoleChecker([], false), s3ClientMiddleware, - async (_req: Request, res: Response) => { + async (_req, res, next) => { const payload = res.locals.payload; const s3 = res.locals.s3 as S3; const userId: string = payload.userId; - const { url, fields } = await createPresignedPost(s3, { - Bucket: Config.S3_BUCKET_NAME, - Key: `${userId}.pdf`, - Conditions: [ - ["content-length-range", 0, Config.MAX_RESUME_SIZE_BYTES], // 6 MB max - ], - Fields: { - success_action_status: "201", - "Content-Type": "application/pdf", - }, - Expires: Config.RESUME_URL_EXPIRY_SECONDS, - }); - - return res.status(StatusCodes.OK).send({ url: url, fields: fields }); + try { + const { url, fields } = await postResumeUrl(userId, s3); + return res.status(StatusCodes.OK).send({ url, fields }); + } catch (error) { + next(error); + } } ); s3Router.get( "/download/", - RoleChecker([Role.enum.USER], false), + RoleChecker([Role.Enum.USER], false), s3ClientMiddleware, - async (_req: Request, res: Response) => { + async (_, res, next) => { const payload = res.locals.payload; + const userId = payload.userId; const s3 = res.locals.s3 as S3; - const userId: string = payload.userId; - - const command = new GetObjectCommand({ - Bucket: Config.S3_BUCKET_NAME, - Key: `${userId}.pdf`, - }); - - const downloadUrl = await getSignedUrl(s3, command, { - expiresIn: Config.RESUME_URL_EXPIRY_SECONDS, - }); - - return res.status(StatusCodes.OK).send({ url: downloadUrl }); + + try { + const downloadUrl = await getResumeUrl(userId, s3); + return res.status(StatusCodes.OK).send({ url: downloadUrl }); + } catch (error) { + next(error); + } } ); s3Router.get( "/download/:USERID", - RoleChecker([Role.enum.STAFF], false), + RoleChecker([Role.Enum.STAFF, Role.Enum.CORPORATE], false), s3ClientMiddleware, - async (req: Request, res: Response) => { - const userId: string = req.params.USERID; + async (req, res, next) => { + const userId = req.params.USERID; const s3 = res.locals.s3 as S3; - const command = new GetObjectCommand({ - Bucket: Config.S3_BUCKET_NAME, - Key: `${userId}.pdf`, - }); - - const downloadUrl = await getSignedUrl(s3, command, { - expiresIn: Config.RESUME_URL_EXPIRY_SECONDS, - }); - - return res.status(StatusCodes.OK).send({ url: downloadUrl }); + try { + const downloadUrl = await getResumeUrl(userId, s3); + return res.status(StatusCodes.OK).send({ url: downloadUrl }); + } catch (error) { + next(error); + } } ); diff --git a/src/services/s3/s3-utils.ts b/src/services/s3/s3-utils.ts new file mode 100644 index 0000000..49d5dbf --- /dev/null +++ b/src/services/s3/s3-utils.ts @@ -0,0 +1,32 @@ +import { GetObjectCommand, S3 } from "@aws-sdk/client-s3"; +import Config from "../../config"; +import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; +import { createPresignedPost } from "@aws-sdk/s3-presigned-post"; + +export async function postResumeUrl(userId: string, client: S3) { + const { url, fields } = await createPresignedPost(client, { + Bucket: Config.S3_BUCKET_NAME, + Key: `${userId}.pdf`, + Conditions: [ + ["content-length-range", 0, Config.MAX_RESUME_SIZE_BYTES], // 6 MB max + ], + Fields: { + success_action_status: "201", + "Content-Type": "application/pdf", + }, + Expires: Config.RESUME_URL_EXPIRY_SECONDS, + }); + + return { url, fields }; +} + +export async function getResumeUrl(userId: string, client: S3) { + const command = new GetObjectCommand({ + Bucket: Config.S3_BUCKET_NAME, + Key: `${userId}.pdf`, + }); + + return getSignedUrl(client, command, { + expiresIn: Config.RESUME_URL_EXPIRY_SECONDS, + }); +} From 2504dd8676f384e48bba3c14e984d65e007574b4 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Fri, 5 Jul 2024 13:16:54 -0700 Subject: [PATCH 14/39] added batch download, needs testing --- src/services/s3/s3-router.ts | 36 ++++++++++++++++++++++++++++++++++-- src/services/s3/s3-schema.ts | 7 +++++++ src/services/s3/s3-utils.ts | 2 +- 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 src/services/s3/s3-schema.ts diff --git a/src/services/s3/s3-router.ts b/src/services/s3/s3-router.ts index 52f631d..2c35fca 100644 --- a/src/services/s3/s3-router.ts +++ b/src/services/s3/s3-router.ts @@ -6,6 +6,7 @@ import { Role } from "../auth/auth-models"; import { S3 } from "@aws-sdk/client-s3"; import { getResumeUrl, postResumeUrl } from "./s3-utils"; +import BatchResumeDownloadValidator from "./s3-schema"; const s3Router: Router = Router(); @@ -37,7 +38,7 @@ s3Router.get( const userId = payload.userId; const s3 = res.locals.s3 as S3; - + try { const downloadUrl = await getResumeUrl(userId, s3); return res.status(StatusCodes.OK).send({ url: downloadUrl }); @@ -48,7 +49,7 @@ s3Router.get( ); s3Router.get( - "/download/:USERID", + "/download/user/:USERID", RoleChecker([Role.Enum.STAFF, Role.Enum.CORPORATE], false), s3ClientMiddleware, async (req, res, next) => { @@ -64,4 +65,35 @@ s3Router.get( } ); +s3Router.get( + "/download/batch/:USERID", + RoleChecker([Role.Enum.STAFF, Role.Enum.CORPORATE], false), + s3ClientMiddleware, + async (req, res, next) => { + const s3 = res.locals.s3 as S3; + + try { + const { userIds } = BatchResumeDownloadValidator.parse(req.body); + + const batchDownloadPromises = userIds.map((userId) => + getResumeUrl(userId, s3) + ); + + const batchDownloadUrls = await Promise.allSettled( + batchDownloadPromises + ); + + const filteredUrls = batchDownloadUrls.forEach((result) => { + if (result.status === "fulfilled") { + return result.value; + } + }); + + return res.status(StatusCodes.OK).send({ url: filteredUrls }); + } catch (error) { + next(error); + } + } +); + export default s3Router; diff --git a/src/services/s3/s3-schema.ts b/src/services/s3/s3-schema.ts new file mode 100644 index 0000000..62ffa53 --- /dev/null +++ b/src/services/s3/s3-schema.ts @@ -0,0 +1,7 @@ +import { z } from "zod"; + +const BatchResumeDownloadValidator = z.object({ + userIds: z.string().array(), +}); + +export default BatchResumeDownloadValidator; diff --git a/src/services/s3/s3-utils.ts b/src/services/s3/s3-utils.ts index 49d5dbf..c6eb2da 100644 --- a/src/services/s3/s3-utils.ts +++ b/src/services/s3/s3-utils.ts @@ -25,7 +25,7 @@ export async function getResumeUrl(userId: string, client: S3) { Bucket: Config.S3_BUCKET_NAME, Key: `${userId}.pdf`, }); - + return getSignedUrl(client, command, { expiresIn: Config.RESUME_URL_EXPIRY_SECONDS, }); From 6d7a61828d50e444576717831c44f92db5ba79b4 Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Sat, 6 Jul 2024 22:15:22 -0700 Subject: [PATCH 15/39] attendee filter body --- src/services/attendees/attendee-router.ts | 22 +++++++++++++++++++++- src/services/attendees/attendee-schema.ts | 10 +++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/services/attendees/attendee-router.ts b/src/services/attendees/attendee-router.ts index f342319..0440ff7 100644 --- a/src/services/attendees/attendee-router.ts +++ b/src/services/attendees/attendee-router.ts @@ -1,6 +1,10 @@ import { Router } from "express"; import { StatusCodes } from "http-status-codes"; -import { AttendeeValidator, EventIdValidator } from "./attendee-schema"; +import { + AttendeeValidator, + EventIdValidator, + PartialAttendeeFilter, +} from "./attendee-schema"; import { Database } from "../../database"; import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; @@ -150,4 +154,20 @@ attendeeRouter.get( } ); +// Get attendees based on a partial filter in body +attendeeRouter.post( + "/filter", + RoleChecker([Role.Enum.ADMIN]), + async (req, res, next) => { + try { + const attendeeData = PartialAttendeeFilter.parse(req.body); + const attendees = await Database.ATTENDEES.find(attendeeData); + + return res.status(StatusCodes.OK).json(attendees); + } catch (error) { + next(error); + } + } +); + export default attendeeRouter; diff --git a/src/services/attendees/attendee-schema.ts b/src/services/attendees/attendee-schema.ts index efe3f43..fd36560 100644 --- a/src/services/attendees/attendee-schema.ts +++ b/src/services/attendees/attendee-schema.ts @@ -62,4 +62,12 @@ const EventIdValidator = z.object({ eventId: z.string().uuid(), }); -export { AttendeeSchema, AttendeeValidator, EventIdValidator }; +// Partial schema for attendee filter +const PartialAttendeeFilter = AttendeeValidator.partial(); + +export { + AttendeeSchema, + AttendeeValidator, + EventIdValidator, + PartialAttendeeFilter, +}; From 4743128c8a0c418f5dcfb34708d7f360009b1ec9 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Sat, 6 Jul 2024 22:26:39 -0700 Subject: [PATCH 16/39] checkin service --- src/services/checkin/checkin-router.ts | 0 src/services/checkin/checkin-utils.ts | 33 +++ src/services/events/events-router.ts | 24 -- src/services/events/events-utils.ts | 35 --- yarn.lock | 346 ++++++++++++++++--------- 5 files changed, 250 insertions(+), 188 deletions(-) create mode 100644 src/services/checkin/checkin-router.ts create mode 100644 src/services/checkin/checkin-utils.ts diff --git a/src/services/checkin/checkin-router.ts b/src/services/checkin/checkin-router.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts new file mode 100644 index 0000000..ac9d313 --- /dev/null +++ b/src/services/checkin/checkin-utils.ts @@ -0,0 +1,33 @@ +import { Database } from "../../database"; + +export async function checkInUserToEvent(eventId: string, userId: string) { + // Check if the event and attendee exist + const [event, attendee] = await Promise.all([ + Database.EVENTS.findOne({ eventId }), + Database.ATTENDEE.findOne({ userId }), + ]); + + if (!event || !attendee) { + return Promise.reject("Event or Attendee not found"); + } + + const eventAttendancePromise = Database.EVENTS_ATTENDANCE.findOneAndUpdate( + { eventId }, + { $addToSet: { attendees: userId } }, + { new: true, upsert: true } + ); + + const attendeeAttendancePromise = + Database.ATTENDEE_ATTENDANCE.findOneAndUpdate( + { userId }, + { $addToSet: { eventsAttended: eventId } }, + { new: true, upsert: true } + ); + + return Promise.all([eventAttendancePromise, attendeeAttendancePromise]) + .then(() => ({ success: true })) + .catch(() => ({ + success: false, + message: "Couldn't upsert event or attendee", + })); +} diff --git a/src/services/events/events-router.ts b/src/services/events/events-router.ts index b620243..0cb8449 100644 --- a/src/services/events/events-router.ts +++ b/src/services/events/events-router.ts @@ -4,7 +4,6 @@ import { Router } from "express"; import { StatusCodes } from "http-status-codes"; import { publicEventValidator, privateEventValidator } from "./events-schema"; import { Database } from "../../database"; -import { checkInUserToEvent } from "./events-utils"; import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; import { isAdmin, isStaff } from "../auth/auth-utils"; @@ -154,27 +153,4 @@ eventsRouter.delete( } ); -eventsRouter.post( - "/check-in", - RoleChecker([Role.Enum.STAFF], true), - async (req, res, next) => { - // add RoleChecker for staff - try { - const { eventId, userId } = req.body; - const result = await checkInUserToEvent(eventId, userId); - if (result.success) { - return res - .status(StatusCodes.OK) - .json({ message: "Check-in successful" }); - } else { - return res - .status(StatusCodes.NOT_FOUND) - .json({ error: result.message }); - } - } catch (error) { - next(error); - } - } -); - export default eventsRouter; diff --git a/src/services/events/events-utils.ts b/src/services/events/events-utils.ts index f3c6cd8..e69de29 100644 --- a/src/services/events/events-utils.ts +++ b/src/services/events/events-utils.ts @@ -1,35 +0,0 @@ -import { Database } from "../../database"; - -export async function checkInUserToEvent(eventId: string, userId: string) { - // Check if the event and attendee exist - const [findEvent, findAttendee] = await Promise.all([ - Database.EVENTS.findOne({ eventId }), - Database.ATTENDEE.findOne({ userId }), - ]); - - if (!findEvent || !findAttendee) { - return { success: false, message: "Event or Attendee not found" }; - } - - try { - // Check or create event attendance record - const eventAttendance = Database.EVENTS_ATTENDANCE.findOneAndUpdate( - { eventId: eventId }, - { $addToSet: { attendees: userId } }, - { new: true, upsert: true } - ); - - // Check or create attendee attendance record - const attendeeAttendance = - Database.ATTENDEE_ATTENDANCE.findOneAndUpdate( - { userId: userId }, - { $addToSet: { eventsAttended: eventId } }, - { new: true, upsert: true } - ); - - await Promise.all([eventAttendance, attendeeAttendance]); - return { success: true }; - } catch (error) { - return { success: false, message: "couldn't upsert event or attendee" }; - } -} diff --git a/yarn.lock b/yarn.lock index bd47243..e69da6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -62,7 +62,7 @@ "@aws-sdk/util-utf8-browser" "^3.0.0" tslib "^1.11.1" -"@aws-crypto/sha256-js@^3.0.0", "@aws-crypto/sha256-js@3.0.0": +"@aws-crypto/sha256-js@3.0.0", "@aws-crypto/sha256-js@^3.0.0": version "3.0.0" resolved "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz" integrity sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ== @@ -87,7 +87,7 @@ "@aws-sdk/util-utf8-browser" "^3.0.0" tslib "^1.11.1" -"@aws-sdk/client-s3@^3.496.0", "@aws-sdk/client-s3@3.590.0": +"@aws-sdk/client-s3@3.590.0", "@aws-sdk/client-s3@^3.496.0": version "3.590.0" resolved "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.590.0.tgz" integrity sha512-so+pNua0ihsHaSdskw8HCwruoYTAfYSEs3ix4GD1++83C96KaJp3udAutYiCA+84JXg9zitFa7eK7ORJAVZmTw== @@ -151,7 +151,7 @@ "@smithy/util-waiter" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/client-sso-oidc@^3.587.0", "@aws-sdk/client-sso-oidc@3.590.0": +"@aws-sdk/client-sso-oidc@3.590.0": version "3.590.0" resolved "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.590.0.tgz" integrity sha512-3yCLPjq6WFfDpdUJKk/gSz4eAPDTjVknXaveMPi2QoVBCshneOnJsV16uNKlpVF1frTHrrDRfKYmbaVh6nFBvQ== @@ -241,7 +241,7 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/client-sts@^3.587.0", "@aws-sdk/client-sts@^3.590.0", "@aws-sdk/client-sts@3.590.0": +"@aws-sdk/client-sts@3.590.0": version "3.590.0" resolved "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.590.0.tgz" integrity sha512-f4R1v1LSn4uLYZ5qj4DyL6gp7PXXzJeJsm2seheiJX+53LSF5L7XSDnQVtX1p9Tevv0hp2YUWUTg6QYwIVSuGg== @@ -581,7 +581,7 @@ "@smithy/types" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/types@^3.222.0", "@aws-sdk/types@3.577.0": +"@aws-sdk/types@3.577.0", "@aws-sdk/types@^3.222.0": version "3.577.0" resolved "https://registry.npmjs.org/@aws-sdk/types/-/types-3.577.0.tgz" integrity sha512-FT2JZES3wBKN/alfmhlo+3ZOq/XJ0C7QOZcDNrpKjB0kqYoKjhVKZ/Hx6ArR0czkKfHzBBEs6y40ebIHx2nSmA== @@ -671,7 +671,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz" integrity sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.8.0", "@babel/core@>=7.0.0-beta.0 <8": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": version "7.24.7" resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz" integrity sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g== @@ -971,11 +971,121 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@esbuild/aix-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" + integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== + +"@esbuild/android-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" + integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== + +"@esbuild/android-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" + integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== + +"@esbuild/android-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" + integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== + "@esbuild/darwin-arm64@0.20.2": version "0.20.2" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz" integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== +"@esbuild/darwin-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" + integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== + +"@esbuild/freebsd-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" + integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== + +"@esbuild/freebsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" + integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== + +"@esbuild/linux-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" + integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== + +"@esbuild/linux-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" + integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== + +"@esbuild/linux-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" + integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== + +"@esbuild/linux-loong64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" + integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== + +"@esbuild/linux-mips64el@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" + integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== + +"@esbuild/linux-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" + integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== + +"@esbuild/linux-riscv64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" + integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== + +"@esbuild/linux-s390x@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" + integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== + +"@esbuild/linux-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" + integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== + +"@esbuild/netbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" + integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== + +"@esbuild/openbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" + integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== + +"@esbuild/sunos-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" + integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== + +"@esbuild/win32-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" + integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== + +"@esbuild/win32-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" + integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== + +"@esbuild/win32-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" + integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== + "@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" @@ -1192,7 +1302,7 @@ jest-haste-map "^29.7.0" slash "^3.0.0" -"@jest/transform@^29.0.0", "@jest/transform@^29.7.0": +"@jest/transform@^29.7.0": version "29.7.0" resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz" integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== @@ -1213,7 +1323,7 @@ slash "^3.0.0" write-file-atomic "^4.0.2" -"@jest/types@^29.0.0", "@jest/types@^29.6.3": +"@jest/types@^29.6.3": version "29.6.3" resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== @@ -1249,14 +1359,6 @@ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.25" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - "@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" @@ -1265,6 +1367,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@mongodb-js/saslprep@^1.1.0", "@mongodb-js/saslprep@^1.1.5": version "1.1.7" resolved "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz" @@ -1285,7 +1395,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -2127,7 +2237,7 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha", "@typescript-eslint/parser@^6.4.0": +"@typescript-eslint/parser@^6.4.0": version "6.21.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz" integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== @@ -2216,7 +2326,7 @@ acorn-walk@^8.1.1: dependencies: acorn "^8.11.0" -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.11.0, acorn@^8.4.1, acorn@^8.9.0: +acorn@^8.11.0, acorn@^8.4.1, acorn@^8.9.0: version "8.11.3" resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== @@ -2440,7 +2550,7 @@ b4a@^1.6.4: resolved "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz" integrity sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg== -babel-jest@^29.0.0, babel-jest@^29.7.0: +babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== @@ -2532,7 +2642,7 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== -body-parser@^1.20.2, body-parser@1.20.2: +body-parser@1.20.2, body-parser@^1.20.2: version "1.20.2" resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== @@ -2577,7 +2687,7 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.22.2, "browserslist@>= 4.21.0": +browserslist@^4.22.2: version "4.23.1" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz" integrity sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw== @@ -2673,12 +2783,7 @@ camelcase@^5.3.1: resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -camelcase@^6.3.0: +camelcase@^6.2.0, camelcase@^6.3.0: version "6.3.0" resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -2768,16 +2873,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" @@ -2921,33 +3026,26 @@ data-view-byte-offset@^1.0.0: es-errors "^1.3.0" is-data-view "^1.0.1" -debug@^2.6.9: +debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@4, debug@4.x: +debug@4, debug@4.x, debug@^4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5: version "4.3.5" resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz" integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== dependencies: ms "2.1.2" -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: - ms "2.0.0" + ms "^2.1.1" dedent@^1.0.0: version "1.5.3" @@ -2987,7 +3085,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@~2.0.0, depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -3274,7 +3372,7 @@ eslint-config-airbnb@19.0.4: object.assign "^4.1.2" object.entries "^1.1.5" -eslint-config-prettier@*, eslint-config-prettier@^9.1.0: +eslint-config-prettier@^9.1.0: version "9.1.0" resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz" integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== @@ -3317,7 +3415,7 @@ eslint-plugin-es-x@^7.5.0: "@eslint-community/regexpp" "^4.6.0" eslint-compat-utils "^0.5.0" -eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.25.3, eslint-plugin-import@2.25.3: +eslint-plugin-import@2.25.3: version "2.25.3" resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz" integrity sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg== @@ -3336,7 +3434,7 @@ eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.25.3, eslint-plugin-import resolve "^1.20.0" tsconfig-paths "^3.11.0" -eslint-plugin-jsx-a11y@^6.5.1, eslint-plugin-jsx-a11y@6.5.1: +eslint-plugin-jsx-a11y@6.5.1: version "6.5.1" resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz" integrity sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g== @@ -3384,12 +3482,12 @@ eslint-plugin-promise@^6.0.0: resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.2.0.tgz" integrity sha512-QmAqwizauvnKOlifxyDj2ObfULpHQawlg/zQdgEixur9vl0CvZGv/LCJV2rtj3210QCoeGBzVMfMXqGAOr/4fA== -eslint-plugin-react-hooks@^4.3.0, eslint-plugin-react-hooks@4.3.0: +eslint-plugin-react-hooks@4.3.0: version "4.3.0" resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz" integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA== -eslint-plugin-react@^7.28.0, eslint-plugin-react@7.28.0: +eslint-plugin-react@7.28.0: version "7.28.0" resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz" integrity sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw== @@ -3434,7 +3532,7 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", "eslint@^7.0.0 || ^8.0.0 || ^9.0.0", "eslint@^7.32.0 || ^8.2.0", eslint@^8.0.1, eslint@>=5, eslint@>=6.0.0, eslint@>=7.0.0, eslint@>=8, eslint@>=8.0.0, eslint@8.2.0: +eslint@8.2.0: version "8.2.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.2.0.tgz" integrity sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw== @@ -3567,7 +3665,7 @@ express-rate-limit@^6.0.0: resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.11.2.tgz" integrity sha512-a7uwwfNTh1U60ssiIkuLFWHt4hAC5yxlLGU2VP0X4YNlyEDZAqF4tK3GD3NSitVBrCQmQ0++0uOyFOgC2y4DDw== -"express@^4 || ^5", express@^4.19.1, "express@4 || 5 || ^5.0.0-beta.1": +express@^4.19.1: version "4.19.2" resolved "https://registry.npmjs.org/express/-/express-4.19.2.tgz" integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== @@ -3630,7 +3728,7 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0, fast-json-stable-stringify@2.x: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -4018,16 +4116,16 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.4: - version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - ieee754@1.1.13: version "1.1.13" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== +ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz" @@ -4072,7 +4170,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.3, inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4541,7 +4639,7 @@ jest-resolve-dependencies@^29.7.0: jest-regex-util "^29.6.3" jest-snapshot "^29.7.0" -jest-resolve@*, jest-resolve@^29.7.0: +jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== @@ -4685,7 +4783,7 @@ jest-worker@^29.7.0: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^29.0.0, jest@^29.7.0: +jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== @@ -4932,7 +5030,7 @@ make-dir@^4.0.0: dependencies: semver "^7.5.3" -make-error@^1.1.1, make-error@1.x: +make-error@1.x, make-error@^1.1.1: version "1.3.6" resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -5009,13 +5107,6 @@ mimic-fn@^2.1.0: resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - minimatch@9.0.3: version "9.0.3" resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" @@ -5023,6 +5114,13 @@ minimatch@9.0.3: dependencies: brace-expansion "^2.0.1" +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -5070,6 +5168,15 @@ mongodb-memory-server@^9.3.0: mongodb-memory-server-core "9.4.0" tslib "^2.6.3" +mongodb@6.6.2: + version "6.6.2" + resolved "https://registry.npmjs.org/mongodb/-/mongodb-6.6.2.tgz" + integrity sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw== + dependencies: + "@mongodb-js/saslprep" "^1.1.5" + bson "^6.7.0" + mongodb-connection-string-url "^3.0.0" + mongodb@^5.9.2: version "5.9.2" resolved "https://registry.npmjs.org/mongodb/-/mongodb-5.9.2.tgz" @@ -5081,15 +5188,6 @@ mongodb@^5.9.2: optionalDependencies: "@mongodb-js/saslprep" "^1.1.0" -mongodb@6.6.2: - version "6.6.2" - resolved "https://registry.npmjs.org/mongodb/-/mongodb-6.6.2.tgz" - integrity sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw== - dependencies: - "@mongodb-js/saslprep" "^1.1.5" - bson "^6.7.0" - mongodb-connection-string-url "^3.0.0" - mongoose@^8.2.3: version "8.4.1" resolved "https://registry.npmjs.org/mongoose/-/mongoose-8.4.1.tgz" @@ -5126,11 +5224,6 @@ mquery@5.0.0: dependencies: debug "4.x" -ms@^2.1.1, ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" @@ -5141,6 +5234,11 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" @@ -5263,13 +5361,6 @@ object.values@^1.1.5, object.values@^1.1.6: define-properties "^1.2.1" es-object-atoms "^1.0.0" -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" - integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== - dependencies: - ee-first "1.1.1" - on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" @@ -5277,6 +5368,13 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== + dependencies: + ee-first "1.1.1" + on-headers@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" @@ -5467,7 +5565,7 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@>=3.0.0, prettier@3.2.5: +prettier@3.2.5: version "3.2.5" resolved "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== @@ -5521,22 +5619,22 @@ pstree.remy@^1.1.8: resolved "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz" integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== -punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0: - version "2.3.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - punycode@1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== +punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0: + version "2.3.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + pure-rand@^6.0.0: version "6.1.0" resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz" integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== -qs@^6.11.0, qs@6.11.0: +qs@6.11.0, qs@^6.11.0: version "6.11.0" resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== @@ -5689,16 +5787,16 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.0.1, safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@5.2.1, safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-regex-test@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz" @@ -5713,27 +5811,17 @@ safe-regex-test@^1.0.3: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@>=0.6.0: - version "1.4.1" - resolved "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz" - integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== - sax@1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz" integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== -semver@^6.0.0: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^6.3.0: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +sax@>=0.6.0: + version "1.4.1" + resolved "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz" + integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== -semver@^6.3.1: +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== @@ -6156,7 +6244,7 @@ ts-jest@^29.1.4: semver "^7.5.3" yargs-parser "^21.0.1" -ts-node@^10.9.2, ts-node@>=9.0.0: +ts-node@^10.9.2: version "10.9.2" resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== @@ -6279,7 +6367,7 @@ typed-array-length@^1.0.6: is-typed-array "^1.1.13" possible-typed-array-names "^1.0.0" -typescript@*, typescript@^5.4.5, typescript@>=2.7, typescript@>=4.2.0, "typescript@>=4.3 <6": +typescript@^5.4.5: version "5.4.5" resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz" integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== @@ -6309,7 +6397,7 @@ undici-types@~5.26.4: resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -unpipe@~1.0.0, unpipe@1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -6348,21 +6436,21 @@ util@^0.12.4: is-typed-array "^1.1.3" which-typed-array "^1.1.2" -utils-merge@^1.0.1, utils-merge@1.0.1, utils-merge@1.x.x: +utils-merge@1.0.1, utils-merge@1.x.x, utils-merge@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^9.0.1: - version "9.0.1" - resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - uuid@8.0.0: version "8.0.0" resolved "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz" integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== +uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" From cc7ccf03ea38f041336cef808ca94ae8fa08045a Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Sat, 6 Jul 2024 22:57:07 -0700 Subject: [PATCH 17/39] fix merge conf --- src/services/attendee/attendee-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/attendee/attendee-router.ts b/src/services/attendee/attendee-router.ts index b8d532c..1a6716b 100644 --- a/src/services/attendee/attendee-router.ts +++ b/src/services/attendee/attendee-router.ts @@ -161,7 +161,7 @@ attendeeRouter.post( async (req, res, next) => { try { const attendeeData = PartialAttendeeFilter.parse(req.body); - const attendees = await Database.ATTENDEES.find(attendeeData); + const attendees = await Database.ATTENDEE.find(attendeeData); return res.status(StatusCodes.OK).json(attendees); } catch (error) { From 36c56925da393b923bea4354177cb533a3f0a884 Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Sat, 6 Jul 2024 23:02:06 -0700 Subject: [PATCH 18/39] fix merge conf --- src/services/attendee/attendee-router.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/attendee/attendee-router.ts b/src/services/attendee/attendee-router.ts index 1a6716b..512a372 100644 --- a/src/services/attendee/attendee-router.ts +++ b/src/services/attendee/attendee-router.ts @@ -3,7 +3,7 @@ import { StatusCodes } from "http-status-codes"; import { AttendeeValidator, EventIdValidator, - PartialAttendeeFilter, + PartialAttendeeValidator, } from "./attendee-schema"; import { Database } from "../../database"; import RoleChecker from "../../middleware/role-checker"; @@ -160,7 +160,7 @@ attendeeRouter.post( RoleChecker([Role.Enum.ADMIN]), async (req, res, next) => { try { - const attendeeData = PartialAttendeeFilter.parse(req.body); + const attendeeData = PartialAttendeeValidator.parse(req.body); const attendees = await Database.ATTENDEE.find(attendeeData); return res.status(StatusCodes.OK).json(attendees); From 98f87096b0c53669305287182e4a5a16cf4dafb5 Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Sat, 6 Jul 2024 23:03:57 -0700 Subject: [PATCH 19/39] fix merge conf --- src/services/attendee/attendee-schema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/attendee/attendee-schema.ts b/src/services/attendee/attendee-schema.ts index 7d6d2fa..d85cc6e 100644 --- a/src/services/attendee/attendee-schema.ts +++ b/src/services/attendee/attendee-schema.ts @@ -75,4 +75,4 @@ export const EventIdValidator = z.object({ }); // Partial schema for attendee filter -export const PartialAttendeeFilter = AttendeeValidator.partial(); +export const PartialAttendeeValidator = AttendeeValidator.partial(); From e62a28c16822435519a54547baf5c9563283628f Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Sat, 6 Jul 2024 23:23:42 -0700 Subject: [PATCH 20/39] clenaed up the code --- package.json | 1 + src/services/attendee/attendee-schema.ts | 46 +++++++++----- src/services/checkin/checkin-utils.ts | 76 ++++++++++++++++++------ yarn.lock | 23 ++++++- 4 files changed, 111 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index b135e76..77e56f5 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "body-parser": "^1.20.2", "cors": "^2.8.5", "crypto": "^1.0.1", + "datetime": "^0.0.3", "dotenv": "^16.4.5", "express": "^4.19.1", "express-rate-limit": "^6.0.0", diff --git a/src/services/attendee/attendee-schema.ts b/src/services/attendee/attendee-schema.ts index a9324d6..177a73d 100644 --- a/src/services/attendee/attendee-schema.ts +++ b/src/services/attendee/attendee-schema.ts @@ -14,18 +14,22 @@ export const AttendeeValidator = z.object({ foodWave: z.number().int().min(0).default(0), hasPriority: z .object({ - dayOne: z.boolean().default(false), - dayTwo: z.boolean().default(false), - dayThree: z.boolean().default(false), - dayFour: z.boolean().default(false), - dayFive: z.boolean().default(false), + Mon: z.boolean().default(false), + Tue: z.boolean().default(false), + Wed: z.boolean().default(false), + Thu: z.boolean().default(false), + Fri: z.boolean().default(false), + Sat: z.boolean().default(false), + Sun: z.boolean().default(false), }) .default({ - dayOne: false, - dayTwo: false, - dayThree: false, - dayFour: false, - dayFive: false, + Mon: false, + Tue: false, + Wed: false, + Thu: false, + Fri: false, + Sat: false, + Sun: false, }), }); @@ -43,15 +47,25 @@ export const AttendeeSchema = new Schema({ hasPriority: { type: new Schema( { - dayOne: { type: Boolean, default: false }, - dayTwo: { type: Boolean, default: false }, - dayThree: { type: Boolean, default: false }, - dayFour: { type: Boolean, default: false }, - dayFive: { type: Boolean, default: false }, + Mon: { type: Boolean, default: false }, + Tue: { type: Boolean, default: false }, + Wed: { type: Boolean, default: false }, + Thu: { type: Boolean, default: false }, + Fri: { type: Boolean, default: false }, + Sat: { type: Boolean, default: false }, + Sun: { type: Boolean, default: false }, }, { _id: false } ), - default: () => ({}), + default: { + Mon: false, + Tue: false, + Wed: false, + Thu: false, + Fri: false, + Sat: false, + Sun: false, + }, }, favorites: [{ type: String }], }); diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index ac9d313..a7b5937 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -1,33 +1,73 @@ import { Database } from "../../database"; -export async function checkInUserToEvent(eventId: string, userId: string) { - // Check if the event and attendee exist +function getCurrentDay() { + const currDate = new Date(); + const dayString = new Intl.DateTimeFormat("en-US", { + timeZone: "America/Chicago", + weekday: "short", + }).format(currDate); + return dayString; +} + +async function checkEventAndAttendeeExist(eventId: string, userId: string): Promise { const [event, attendee] = await Promise.all([ - Database.EVENTS.findOne({ eventId }), - Database.ATTENDEE.findOne({ userId }), + Database.EVENTS.exists({ eventId }), + Database.ATTENDEE.exists({ userId }), ]); if (!event || !attendee) { - return Promise.reject("Event or Attendee not found"); + throw new Error("Event or Attendee not found"); + } + + return Promise.resolve(); +} + +async function checkForDuplicateAttendance(eventId: string, userId: string): Promise { + const [isRepeatEvent, isRepeatAttendee] = await Promise.all([ + Database.EVENTS_ATTENDANCE.exists({ eventId, attendees: userId }), + Database.ATTENDEE_ATTENDANCE.exists({ userId, eventsAttended: eventId }), + ]); + + if (isRepeatEvent || isRepeatAttendee) { + throw new Error("Is Duplicate"); } +} - const eventAttendancePromise = Database.EVENTS_ATTENDANCE.findOneAndUpdate( - { eventId }, - { $addToSet: { attendees: userId } }, - { new: true, upsert: true } +// Update attendee priority for the current day +async function updateAttendeePriority(userId: string): Promise { + const day = getCurrentDay(); + await Database.ATTENDEE.findOneAndUpdate( + { userId }, + { $set: { [`hasPriority.${day}`]: true } } ); +} - const attendeeAttendancePromise = +async function updateAttendanceRecords(eventId: string, userId: string): Promise { + await Promise.all([ + Database.EVENTS_ATTENDANCE.findOneAndUpdate( + { eventId }, + { $addToSet: { attendees: userId } }, + { new: true, upsert: true } + ), Database.ATTENDEE_ATTENDANCE.findOneAndUpdate( { userId }, { $addToSet: { eventsAttended: eventId } }, { new: true, upsert: true } - ); - - return Promise.all([eventAttendancePromise, attendeeAttendancePromise]) - .then(() => ({ success: true })) - .catch(() => ({ - success: false, - message: "Couldn't upsert event or attendee", - })); + ), + ]); +} + +export async function checkInUserToEvent(eventId: string, userId: string, isCheckin: boolean = false): Promise { + try { + await checkEventAndAttendeeExist(eventId, userId); + await checkForDuplicateAttendance(eventId, userId); + + if (isCheckin) { + await updateAttendeePriority(userId); + } + + await updateAttendanceRecords(eventId, userId); + } catch (error) { + return Promise.reject(error); + } } diff --git a/yarn.lock b/yarn.lock index e69da6b..e949d7d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3026,6 +3026,13 @@ data-view-byte-offset@^1.0.0: es-errors "^1.3.0" is-data-view "^1.0.1" +datetime@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/datetime/-/datetime-0.0.3.tgz#fa9086d20f81d54e7776a8180ee7320ae367ed78" + integrity sha512-7Y3rDInvMV5V/ZiIUFJb12t8wO+lNpcLyE0Za5FEZOtXFQmr/NK/E8EtXkhKH82N6Shi30VuyaAqUHS45ilsQA== + dependencies: + vows ">=0.5.4" + debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" @@ -3702,6 +3709,11 @@ express@^4.19.1: utils-merge "1.0.1" vary "~1.1.2" +eyes@~0.1.6: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + integrity sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -3958,7 +3970,7 @@ glob-parent@^6.0.1: dependencies: is-glob "^4.0.3" -glob@^7.1.3, glob@^7.1.4: +glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -6475,6 +6487,15 @@ vary@^1, vary@~1.1.2: resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +vows@>=0.5.4: + version "0.8.3" + resolved "https://registry.yarnpkg.com/vows/-/vows-0.8.3.tgz#36e353c2bca3a93902fc32eb8c5baab2e3a93f10" + integrity sha512-PVIxa/ovXhrw5gA3mz6M+ZF3PHlqX4tutR2p/y9NWPAaFVKcWBE8b2ktfr0opQM/qFmcOVWKjSCJVjnYOvjXhw== + dependencies: + diff "^4.0.1" + eyes "~0.1.6" + glob "^7.1.2" + walker@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" From 099b40b51e3371d15ccac7984770fe5745c4e868 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Sat, 6 Jul 2024 23:25:39 -0700 Subject: [PATCH 21/39] linter fixes --- src/services/checkin/checkin-utils.ts | 28 +++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index a7b5937..cc0938f 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -9,7 +9,10 @@ function getCurrentDay() { return dayString; } -async function checkEventAndAttendeeExist(eventId: string, userId: string): Promise { +async function checkEventAndAttendeeExist( + eventId: string, + userId: string +): Promise { const [event, attendee] = await Promise.all([ Database.EVENTS.exists({ eventId }), Database.ATTENDEE.exists({ userId }), @@ -18,14 +21,20 @@ async function checkEventAndAttendeeExist(eventId: string, userId: string): Prom if (!event || !attendee) { throw new Error("Event or Attendee not found"); } - + return Promise.resolve(); } -async function checkForDuplicateAttendance(eventId: string, userId: string): Promise { +async function checkForDuplicateAttendance( + eventId: string, + userId: string +): Promise { const [isRepeatEvent, isRepeatAttendee] = await Promise.all([ Database.EVENTS_ATTENDANCE.exists({ eventId, attendees: userId }), - Database.ATTENDEE_ATTENDANCE.exists({ userId, eventsAttended: eventId }), + Database.ATTENDEE_ATTENDANCE.exists({ + userId, + eventsAttended: eventId, + }), ]); if (isRepeatEvent || isRepeatAttendee) { @@ -42,7 +51,10 @@ async function updateAttendeePriority(userId: string): Promise { ); } -async function updateAttendanceRecords(eventId: string, userId: string): Promise { +async function updateAttendanceRecords( + eventId: string, + userId: string +): Promise { await Promise.all([ Database.EVENTS_ATTENDANCE.findOneAndUpdate( { eventId }, @@ -57,7 +69,11 @@ async function updateAttendanceRecords(eventId: string, userId: string): Promise ]); } -export async function checkInUserToEvent(eventId: string, userId: string, isCheckin: boolean = false): Promise { +export async function checkInUserToEvent( + eventId: string, + userId: string, + isCheckin: boolean = false +): Promise { try { await checkEventAndAttendeeExist(eventId, userId); await checkForDuplicateAttendance(eventId, userId); From 2a717dadf01548b7b4784f2a4d8961feaffa1736 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Sat, 6 Jul 2024 23:27:45 -0700 Subject: [PATCH 22/39] cleaned this up more --- src/services/checkin/checkin-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index cc0938f..a1bbcaa 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -78,7 +78,7 @@ export async function checkInUserToEvent( await checkEventAndAttendeeExist(eventId, userId); await checkForDuplicateAttendance(eventId, userId); - if (isCheckin) { + if (!isCheckin) { await updateAttendeePriority(userId); } From 30b84a8d734dd39c755f838e29dbc7ac4f7f32ec Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Sat, 6 Jul 2024 23:31:37 -0700 Subject: [PATCH 23/39] Cleaned up empty file --- src/services/events/events-utils.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/services/events/events-utils.ts diff --git a/src/services/events/events-utils.ts b/src/services/events/events-utils.ts deleted file mode 100644 index e69de29..0000000 From 0870a491d179c761384b12c946e2c963b0b83be1 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Sat, 6 Jul 2024 23:35:58 -0700 Subject: [PATCH 24/39] Fixed promise --- src/services/checkin/checkin-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index a1bbcaa..0762535 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -84,6 +84,6 @@ export async function checkInUserToEvent( await updateAttendanceRecords(eventId, userId); } catch (error) { - return Promise.reject(error); + throw error; } } From c4eab11bbb5a89b6128577641f34c17cac4df1b6 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Sat, 6 Jul 2024 23:36:46 -0700 Subject: [PATCH 25/39] removed the return type annotations --- src/services/checkin/checkin-utils.ts | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index 0762535..ae86a27 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -9,10 +9,7 @@ function getCurrentDay() { return dayString; } -async function checkEventAndAttendeeExist( - eventId: string, - userId: string -): Promise { +async function checkEventAndAttendeeExist(eventId: string, userId: string) { const [event, attendee] = await Promise.all([ Database.EVENTS.exists({ eventId }), Database.ATTENDEE.exists({ userId }), @@ -25,10 +22,7 @@ async function checkEventAndAttendeeExist( return Promise.resolve(); } -async function checkForDuplicateAttendance( - eventId: string, - userId: string -): Promise { +async function checkForDuplicateAttendance(eventId: string, userId: string) { const [isRepeatEvent, isRepeatAttendee] = await Promise.all([ Database.EVENTS_ATTENDANCE.exists({ eventId, attendees: userId }), Database.ATTENDEE_ATTENDANCE.exists({ @@ -43,7 +37,7 @@ async function checkForDuplicateAttendance( } // Update attendee priority for the current day -async function updateAttendeePriority(userId: string): Promise { +async function updateAttendeePriority(userId: string) { const day = getCurrentDay(); await Database.ATTENDEE.findOneAndUpdate( { userId }, @@ -51,10 +45,7 @@ async function updateAttendeePriority(userId: string): Promise { ); } -async function updateAttendanceRecords( - eventId: string, - userId: string -): Promise { +async function updateAttendanceRecords(eventId: string, userId: string) { await Promise.all([ Database.EVENTS_ATTENDANCE.findOneAndUpdate( { eventId }, @@ -73,7 +64,7 @@ export async function checkInUserToEvent( eventId: string, userId: string, isCheckin: boolean = false -): Promise { +) { try { await checkEventAndAttendeeExist(eventId, userId); await checkForDuplicateAttendance(eventId, userId); From 97c6723746bb87b2fee97bce50446111b7b19d1d Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Sat, 6 Jul 2024 23:38:21 -0700 Subject: [PATCH 26/39] removed try catch --- src/services/checkin/checkin-utils.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index ae86a27..c16b20b 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -65,16 +65,12 @@ export async function checkInUserToEvent( userId: string, isCheckin: boolean = false ) { - try { - await checkEventAndAttendeeExist(eventId, userId); - await checkForDuplicateAttendance(eventId, userId); + await checkEventAndAttendeeExist(eventId, userId); + await checkForDuplicateAttendance(eventId, userId); - if (!isCheckin) { - await updateAttendeePriority(userId); - } - - await updateAttendanceRecords(eventId, userId); - } catch (error) { - throw error; + if (!isCheckin) { + await updateAttendeePriority(userId); } + + await updateAttendanceRecords(eventId, userId); } From 8977e06eea8adb301e35221b2a23c926c2d02e58 Mon Sep 17 00:00:00 2001 From: Aydan Pirani Date: Sun, 7 Jul 2024 00:14:53 -0700 Subject: [PATCH 27/39] Added userId support --- src/services/s3/s3-router.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/services/s3/s3-router.ts b/src/services/s3/s3-router.ts index 2c35fca..9902c8a 100644 --- a/src/services/s3/s3-router.ts +++ b/src/services/s3/s3-router.ts @@ -66,7 +66,7 @@ s3Router.get( ); s3Router.get( - "/download/batch/:USERID", + "/download/batch/", RoleChecker([Role.Enum.STAFF, Role.Enum.CORPORATE], false), s3ClientMiddleware, async (req, res, next) => { @@ -77,19 +77,27 @@ s3Router.get( const batchDownloadPromises = userIds.map((userId) => getResumeUrl(userId, s3) + .then((url) => ({ userId, url: url })) + .catch(() => ({ userId, url: null })) ); - - const batchDownloadUrls = await Promise.allSettled( + + const batchDownloadResults = await Promise.allSettled( batchDownloadPromises ); - const filteredUrls = batchDownloadUrls.forEach((result) => { + const filteredUrls = batchDownloadResults.forEach((result) => { if (result.status === "fulfilled") { return result.value; } }); - return res.status(StatusCodes.OK).send({ url: filteredUrls }); + const errors = batchDownloadResults.filter( + (result) => result.status === "rejected" + ).length; + + return res + .status(StatusCodes.OK) + .send({ data: filteredUrls, errorCount: errors }); } catch (error) { next(error); } From 718a60942859920a625090d667f85fd396501e4d Mon Sep 17 00:00:00 2001 From: Jacob Chang Date: Sun, 7 Jul 2024 09:22:04 -0700 Subject: [PATCH 28/39] fix comments --- src/services/attendee/attendee-router.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/services/attendee/attendee-router.ts b/src/services/attendee/attendee-router.ts index 512a372..1fb2187 100644 --- a/src/services/attendee/attendee-router.ts +++ b/src/services/attendee/attendee-router.ts @@ -155,13 +155,16 @@ attendeeRouter.get( ); // Get attendees based on a partial filter in body -attendeeRouter.post( +attendeeRouter.get( "/filter", - RoleChecker([Role.Enum.ADMIN]), + RoleChecker([Role.Enum.STAFF, Role.Enum.CORPORATE]), async (req, res, next) => { try { const attendeeData = PartialAttendeeValidator.parse(req.body); - const attendees = await Database.ATTENDEE.find(attendeeData); + const attendees = await Database.ATTENDEE.find( + attendeeData, + "userId" + ); return res.status(StatusCodes.OK).json(attendees); } catch (error) { From 278460d0374005b67df9c445def533b870be9c49 Mon Sep 17 00:00:00 2001 From: Alex Yang <32620988+DatProJack@users.noreply.github.com> Date: Mon, 8 Jul 2024 13:20:34 -0500 Subject: [PATCH 29/39] scrips fix --- scripts/install_dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install_dependencies.sh b/scripts/install_dependencies.sh index a2d1598..7c6a9c1 100644 --- a/scripts/install_dependencies.sh +++ b/scripts/install_dependencies.sh @@ -8,5 +8,5 @@ RUNNING=$? if [ "${RUNNING}" -eq 1 ]; then -sudo pm2 start build/app.js --name RP_API -i 2 --wait-ready --listen-timeout 10000 +sudo pm2 start build/src/app.js --name RP_API -i 2 --wait-ready --listen-timeout 10000 fi; From 57bc1cb1f58f8998fbe42bb4908c35cc475cd14c Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Tue, 9 Jul 2024 00:33:05 -0500 Subject: [PATCH 30/39] renamed endpoint --- src/services/admin/admin-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 06af25e..9df9652 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -10,7 +10,7 @@ import { validateQrHash } from "../attendees/attendees-utils"; const adminRouter = Router(); adminRouter.post( - "/scan/", + "/checkin/scan/staff", RoleChecker([Role.Enum.ADMIN]), async (req, res, next) => { try { From 1d38c4967704572fc3284f75c00e37ad342cd361 Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Tue, 9 Jul 2024 00:41:00 -0500 Subject: [PATCH 31/39] lint --- src/services/admin/admin-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 7d9b02b..5f1ba5d 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -30,7 +30,7 @@ adminRouter.post( .json({ error: "QR code has expired" }); } - const user = await Database.ATTENDEES.findOne({ userId }); + const user = await Database.ATTENDEE.findOne({ userId }); if (!user) { return res From fbee0732132268941d4775de3d836d71cfbd9d11 Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Tue, 9 Jul 2024 00:56:08 -0500 Subject: [PATCH 32/39] modified check-in router --- src/services/admin/admin-router.ts | 2 +- src/services/checkin/checkin-router.ts | 43 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts index 8cc64af..7e14cba 100644 --- a/src/services/admin/admin-router.ts +++ b/src/services/admin/admin-router.ts @@ -10,7 +10,7 @@ import { validateQrHash } from "../attendee/attendee-utils"; const adminRouter = Router(); adminRouter.post( - "/checkin/scan/staff", + "/scan/", RoleChecker([Role.Enum.ADMIN]), async (req, res, next) => { try { diff --git a/src/services/checkin/checkin-router.ts b/src/services/checkin/checkin-router.ts index e69de29..d779339 100644 --- a/src/services/checkin/checkin-router.ts +++ b/src/services/checkin/checkin-router.ts @@ -0,0 +1,43 @@ +import { Router } from "express"; +import { StatusCodes } from "http-status-codes"; +import { ScanValidator } from "../admin/admin-schema"; +import { Database } from "../../database"; +import RoleChecker from "../../middleware/role-checker"; +import { Role } from "../auth/auth-models"; +// import dotenv from "dotenv"; +import { validateQrHash } from "../attendee/attendee-utils"; + +const adminRouter = Router(); + +adminRouter.post( + "/checkin/scan/staff", + RoleChecker([Role.Enum.ADMIN]), + async (req, res, next) => { + try { + const { eventId, qrCode } = ScanValidator.parse(req.body); + console.log("Event ID:", eventId); + + const { userId, expTime } = validateQrHash(qrCode); + + if (Date.now() / 1000 > expTime) { + return res + .status(StatusCodes.UNAUTHORIZED) + .json({ error: "QR code has expired" }); + } + + const user = await Database.ATTENDEE.findOne({ userId }); + + if (!user) { + return res + .status(StatusCodes.NOT_FOUND) + .json({ error: "UserNotFound" }); + } + + return res.status(StatusCodes.OK).json(user); + } catch (error) { + next(error); + } + } +); + +export default adminRouter; \ No newline at end of file From 970e4d45db122c33a6b20ad1bc2d37fe98034973 Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Tue, 9 Jul 2024 01:25:28 -0500 Subject: [PATCH 33/39] modified --- src/services/admin/admin-router.ts | 43 -------------------------- src/services/checkin/checkin-schema.ts | 8 +++++ 2 files changed, 8 insertions(+), 43 deletions(-) delete mode 100644 src/services/admin/admin-router.ts create mode 100644 src/services/checkin/checkin-schema.ts diff --git a/src/services/admin/admin-router.ts b/src/services/admin/admin-router.ts deleted file mode 100644 index 7e14cba..0000000 --- a/src/services/admin/admin-router.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Router } from "express"; -import { StatusCodes } from "http-status-codes"; -import { ScanValidator } from "./admin-schema"; -import { Database } from "../../database"; -import RoleChecker from "../../middleware/role-checker"; -import { Role } from "../auth/auth-models"; -// import dotenv from "dotenv"; -import { validateQrHash } from "../attendee/attendee-utils"; - -const adminRouter = Router(); - -adminRouter.post( - "/scan/", - RoleChecker([Role.Enum.ADMIN]), - async (req, res, next) => { - try { - const { eventId, qrCode } = ScanValidator.parse(req.body); - console.log("Event ID:", eventId); - - const { userId, expTime } = validateQrHash(qrCode); - - if (Date.now() / 1000 > expTime) { - return res - .status(StatusCodes.UNAUTHORIZED) - .json({ error: "QR code has expired" }); - } - - const user = await Database.ATTENDEE.findOne({ userId }); - - if (!user) { - return res - .status(StatusCodes.NOT_FOUND) - .json({ error: "UserNotFound" }); - } - - return res.status(StatusCodes.OK).json(user); - } catch (error) { - next(error); - } - } -); - -export default adminRouter; diff --git a/src/services/checkin/checkin-schema.ts b/src/services/checkin/checkin-schema.ts new file mode 100644 index 0000000..c0b7c0a --- /dev/null +++ b/src/services/checkin/checkin-schema.ts @@ -0,0 +1,8 @@ +import { z } from "zod"; + +const ScanValidator = z.object({ + eventId: z.string(), + qrCode: z.string(), +}); + +export { ScanValidator }; From 3515ca99efdb6e17cbf341e18179b44a39ffdc22 Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Tue, 9 Jul 2024 01:28:08 -0500 Subject: [PATCH 34/39] lint? --- src/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.ts b/src/app.ts index a473fb6..0707619 100644 --- a/src/app.ts +++ b/src/app.ts @@ -11,7 +11,7 @@ import bodyParser from "body-parser"; import errorHandler from "./middleware/error-handler"; import attendeeRouter from "./services/attendee/attendee-router"; -import adminRouter from "./services/admin/admin-router"; +import adminRouter from "./services/checkin/checkin-router"; import authRouter from "./services/auth/auth-router"; import eventsRouter from "./services/events/events-router"; import notificationsRouter from "./services/notifications/notifications-router"; From a2b2c12700b3518d87d769243014a8d07101dde1 Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Tue, 9 Jul 2024 01:30:14 -0500 Subject: [PATCH 35/39] all files --- src/services/admin/admin-schema.ts | 8 -------- src/services/checkin/checkin-router.ts | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 src/services/admin/admin-schema.ts diff --git a/src/services/admin/admin-schema.ts b/src/services/admin/admin-schema.ts deleted file mode 100644 index c0b7c0a..0000000 --- a/src/services/admin/admin-schema.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { z } from "zod"; - -const ScanValidator = z.object({ - eventId: z.string(), - qrCode: z.string(), -}); - -export { ScanValidator }; diff --git a/src/services/checkin/checkin-router.ts b/src/services/checkin/checkin-router.ts index d779339..76f336f 100644 --- a/src/services/checkin/checkin-router.ts +++ b/src/services/checkin/checkin-router.ts @@ -1,6 +1,6 @@ import { Router } from "express"; import { StatusCodes } from "http-status-codes"; -import { ScanValidator } from "../admin/admin-schema"; +import { ScanValidator } from "./checkin-schema"; import { Database } from "../../database"; import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; @@ -40,4 +40,4 @@ adminRouter.post( } ); -export default adminRouter; \ No newline at end of file +export default adminRouter; From eb162442436b7f8c0264a8c63497c460b8a5d8ab Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Tue, 9 Jul 2024 09:44:28 -0500 Subject: [PATCH 36/39] called check in func --- src/services/checkin/checkin-router.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/services/checkin/checkin-router.ts b/src/services/checkin/checkin-router.ts index 76f336f..0b3c67a 100644 --- a/src/services/checkin/checkin-router.ts +++ b/src/services/checkin/checkin-router.ts @@ -6,6 +6,7 @@ import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; // import dotenv from "dotenv"; import { validateQrHash } from "../attendee/attendee-utils"; +import { checkInUserToEvent } from "./checkin-utils"; const adminRouter = Router(); @@ -33,6 +34,8 @@ adminRouter.post( .json({ error: "UserNotFound" }); } + await checkInUserToEvent(eventId, userId, true); + return res.status(StatusCodes.OK).json(user); } catch (error) { next(error); From 2cb84430e9c6e51ad5b71edcaf5a4c0e38e2342e Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Tue, 9 Jul 2024 11:09:22 -0500 Subject: [PATCH 37/39] lint --- src/services/checkin/checkin-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/checkin/checkin-router.ts b/src/services/checkin/checkin-router.ts index 0b3c67a..2dbafa5 100644 --- a/src/services/checkin/checkin-router.ts +++ b/src/services/checkin/checkin-router.ts @@ -6,7 +6,7 @@ import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; // import dotenv from "dotenv"; import { validateQrHash } from "../attendee/attendee-utils"; -import { checkInUserToEvent } from "./checkin-utils"; +import { checkInUserToEvent } from "./checkin-utils"; const adminRouter = Router(); From 90f5d87bf0223ddeadb26e6dcd022fde2cc4a06d Mon Sep 17 00:00:00 2001 From: sdagg9 <113925197+sdagg9@users.noreply.github.com> Date: Thu, 11 Jul 2024 00:15:08 -0500 Subject: [PATCH 38/39] Update src/services/checkin/checkin-router.ts Co-authored-by: Aydan Pirani --- src/services/checkin/checkin-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/checkin/checkin-router.ts b/src/services/checkin/checkin-router.ts index 2dbafa5..6f2c635 100644 --- a/src/services/checkin/checkin-router.ts +++ b/src/services/checkin/checkin-router.ts @@ -11,7 +11,7 @@ import { checkInUserToEvent } from "./checkin-utils"; const adminRouter = Router(); adminRouter.post( - "/checkin/scan/staff", + "/scan/staff", RoleChecker([Role.Enum.ADMIN]), async (req, res, next) => { try { From adc02093404a6c74185ada8d6e21e07e5ded4be6 Mon Sep 17 00:00:00 2001 From: Shreenija Reddy Daggavolu Date: Thu, 11 Jul 2024 00:30:00 -0500 Subject: [PATCH 39/39] made changes to checkin --- src/app.ts | 4 +-- src/services/attendee/attendee-router.ts | 2 +- src/services/attendee/attendee-utils.ts | 31 ------------------------ src/services/checkin/checkin-router.ts | 20 ++++----------- src/services/checkin/checkin-utils.ts | 31 ++++++++++++++++++++++++ 5 files changed, 39 insertions(+), 49 deletions(-) delete mode 100644 src/services/attendee/attendee-utils.ts diff --git a/src/app.ts b/src/app.ts index 0707619..3717c2f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -11,7 +11,7 @@ import bodyParser from "body-parser"; import errorHandler from "./middleware/error-handler"; import attendeeRouter from "./services/attendee/attendee-router"; -import adminRouter from "./services/checkin/checkin-router"; +import checkinRouter from "./services/checkin/checkin-router"; import authRouter from "./services/auth/auth-router"; import eventsRouter from "./services/events/events-router"; import notificationsRouter from "./services/notifications/notifications-router"; @@ -38,8 +38,8 @@ app.use("/", bodyParser.json()); // API routes app.use("/attendee", databaseMiddleware, attendeeRouter); -app.use("/admin", databaseMiddleware, adminRouter); app.use("/auth", databaseMiddleware, authRouter); +app.use("/checkin", databaseMiddleware, checkinRouter); app.use("/events", databaseMiddleware, eventsRouter); app.use("/notifications", databaseMiddleware, notificationsRouter); app.use("/registration", databaseMiddleware, registrationRouter); diff --git a/src/services/attendee/attendee-router.ts b/src/services/attendee/attendee-router.ts index 1fb2187..d00295a 100644 --- a/src/services/attendee/attendee-router.ts +++ b/src/services/attendee/attendee-router.ts @@ -9,7 +9,7 @@ import { Database } from "../../database"; import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; import dotenv from "dotenv"; -import { generateQrHash } from "./attendee-utils"; +import { generateQrHash } from "../checkin/checkin-utils"; dotenv.config(); diff --git a/src/services/attendee/attendee-utils.ts b/src/services/attendee/attendee-utils.ts deleted file mode 100644 index 6af110b..0000000 --- a/src/services/attendee/attendee-utils.ts +++ /dev/null @@ -1,31 +0,0 @@ -import crypto from "crypto"; -import { Config } from "../../config"; - -export function generateQrHash(userId: string, expTime: number) { - let hashStr = userId + "#" + expTime; - const hashIterations = Config.QR_HASH_ITERATIONS; - const hashSecret = Config.QR_HASH_SECRET; - - const hmac = crypto.createHmac("sha256", hashSecret); - hashStr = hmac.update(hashStr).digest("hex"); - - for (let i = 0; i < hashIterations; i++) { - const hash = crypto.createHash("sha256"); - hashStr = hash.update(hashSecret + "#" + hashStr).digest("hex"); - } - - return `${hashStr}#${expTime}#${userId}`; -} - -export function validateQrHash(qrCode: string) { - const parts = qrCode.split("#"); - const userId = parts[2]; - const expTime = parseInt(parts[1]); - const generatedHash = generateQrHash(userId, expTime); - - if (generatedHash.split("#")[0] !== parts[0]) { - throw new Error("Invalid QR code"); - } - - return { userId, expTime }; -} diff --git a/src/services/checkin/checkin-router.ts b/src/services/checkin/checkin-router.ts index 6f2c635..f5f4558 100644 --- a/src/services/checkin/checkin-router.ts +++ b/src/services/checkin/checkin-router.ts @@ -1,16 +1,14 @@ import { Router } from "express"; import { StatusCodes } from "http-status-codes"; import { ScanValidator } from "./checkin-schema"; -import { Database } from "../../database"; import RoleChecker from "../../middleware/role-checker"; import { Role } from "../auth/auth-models"; -// import dotenv from "dotenv"; -import { validateQrHash } from "../attendee/attendee-utils"; +import { validateQrHash } from "./checkin-utils"; import { checkInUserToEvent } from "./checkin-utils"; -const adminRouter = Router(); +const checkinRouter = Router(); -adminRouter.post( +checkinRouter.post( "/scan/staff", RoleChecker([Role.Enum.ADMIN]), async (req, res, next) => { @@ -26,21 +24,13 @@ adminRouter.post( .json({ error: "QR code has expired" }); } - const user = await Database.ATTENDEE.findOne({ userId }); - - if (!user) { - return res - .status(StatusCodes.NOT_FOUND) - .json({ error: "UserNotFound" }); - } - await checkInUserToEvent(eventId, userId, true); - return res.status(StatusCodes.OK).json(user); + return res.status(StatusCodes.OK).json(userId); } catch (error) { next(error); } } ); -export default adminRouter; +export default checkinRouter; diff --git a/src/services/checkin/checkin-utils.ts b/src/services/checkin/checkin-utils.ts index c16b20b..8a326a6 100644 --- a/src/services/checkin/checkin-utils.ts +++ b/src/services/checkin/checkin-utils.ts @@ -1,4 +1,6 @@ import { Database } from "../../database"; +import crypto from "crypto"; +import { Config } from "../../config"; function getCurrentDay() { const currDate = new Date(); @@ -74,3 +76,32 @@ export async function checkInUserToEvent( await updateAttendanceRecords(eventId, userId); } + +export function generateQrHash(userId: string, expTime: number) { + let hashStr = userId + "#" + expTime; + const hashIterations = Config.QR_HASH_ITERATIONS; + const hashSecret = Config.QR_HASH_SECRET; + + const hmac = crypto.createHmac("sha256", hashSecret); + hashStr = hmac.update(hashStr).digest("hex"); + + for (let i = 0; i < hashIterations; i++) { + const hash = crypto.createHash("sha256"); + hashStr = hash.update(hashSecret + "#" + hashStr).digest("hex"); + } + + return `${hashStr}#${expTime}#${userId}`; +} + +export function validateQrHash(qrCode: string) { + const parts = qrCode.split("#"); + const userId = parts[2]; + const expTime = parseInt(parts[1]); + const generatedHash = generateQrHash(userId, expTime); + + if (generatedHash.split("#")[0] !== parts[0]) { + throw new Error("Invalid QR code"); + } + + return { userId, expTime }; +}