Skip to content

Commit

Permalink
Merge pull request #74 from ReflectionsProjections/dev/sdagg9/admin-scan
Browse files Browse the repository at this point in the history
admin scan endpoint
  • Loading branch information
AydanPirani authored Jul 11, 2024
2 parents 0d17813 + adc0209 commit 1308987
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 74 deletions.
2 changes: 2 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import bodyParser from "body-parser";
import errorHandler from "./middleware/error-handler";

import attendeeRouter from "./services/attendee/attendee-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";
Expand Down Expand Up @@ -38,6 +39,7 @@ app.use("/", bodyParser.json());
// API routes
app.use("/attendee", databaseMiddleware, attendeeRouter);
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);
Expand Down
2 changes: 1 addition & 1 deletion src/services/attendee/attendee-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
18 changes: 0 additions & 18 deletions src/services/attendee/attendee-utils.ts

This file was deleted.

36 changes: 36 additions & 0 deletions src/services/checkin/checkin-router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Router } from "express";
import { StatusCodes } from "http-status-codes";
import { ScanValidator } from "./checkin-schema";
import RoleChecker from "../../middleware/role-checker";
import { Role } from "../auth/auth-models";
import { validateQrHash } from "./checkin-utils";
import { checkInUserToEvent } from "./checkin-utils";

const checkinRouter = Router();

checkinRouter.post(
"/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" });
}

await checkInUserToEvent(eventId, userId, true);

return res.status(StatusCodes.OK).json(userId);
} catch (error) {
next(error);
}
}
);

export default checkinRouter;
8 changes: 8 additions & 0 deletions src/services/checkin/checkin-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { z } from "zod";

const ScanValidator = z.object({
eventId: z.string(),
qrCode: z.string(),
});

export { ScanValidator };
31 changes: 31 additions & 0 deletions src/services/checkin/checkin-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Database } from "../../database";
import crypto from "crypto";
import { Config } from "../../config";

function getCurrentDay() {
const currDate = new Date();
Expand Down Expand Up @@ -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 };
}
69 changes: 14 additions & 55 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -925,52 +925,6 @@
dependencies:
regenerator-runtime "^0.14.0"

"@babel/template@^7.24.7", "@babel/template@^7.3.3":
version "7.24.7"
resolved "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz"
integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==
dependencies:
"@babel/code-frame" "^7.24.7"
"@babel/parser" "^7.24.7"
"@babel/types" "^7.24.7"

"@babel/traverse@^7.24.7":
version "7.24.7"
resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz"
integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==
dependencies:
"@babel/code-frame" "^7.24.7"
"@babel/generator" "^7.24.7"
"@babel/helper-environment-visitor" "^7.24.7"
"@babel/helper-function-name" "^7.24.7"
"@babel/helper-hoist-variables" "^7.24.7"
"@babel/helper-split-export-declaration" "^7.24.7"
"@babel/parser" "^7.24.7"
"@babel/types" "^7.24.7"
debug "^4.3.1"
globals "^11.1.0"

"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.3.3":
version "7.24.7"
resolved "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz"
integrity sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==
dependencies:
"@babel/helper-string-parser" "^7.24.7"
"@babel/helper-validator-identifier" "^7.24.7"
to-fast-properties "^2.0.0"

"@bcoe/v8-coverage@^0.2.3":
version "0.2.3"
resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==

"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz"
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
dependencies:
"@jridgewell/trace-mapping" "0.3.9"

"@esbuild/[email protected]":
version "0.20.2"
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537"
Expand Down Expand Up @@ -3040,7 +2994,7 @@ [email protected], debug@^2.6.9:
dependencies:
ms "2.0.0"

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:
[email protected], debug@^4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.5"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz"
integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
Expand Down Expand Up @@ -3146,11 +3100,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==

[email protected]:
version "1.0.11"
resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz"
Expand Down Expand Up @@ -5128,7 +5087,7 @@ [email protected]:

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"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
Expand Down Expand Up @@ -5248,7 +5207,7 @@ [email protected]:

[email protected], ms@^2.1.1:
version "2.1.3"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==

natural-compare@^1.4.0:
Expand Down Expand Up @@ -5375,14 +5334,14 @@ object.values@^1.1.5, object.values@^1.1.6:

[email protected]:
version "2.4.1"
resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
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"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==
dependencies:
ee-first "1.1.1"
Expand Down Expand Up @@ -5638,7 +5597,7 @@ [email protected]:

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"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==

pure-rand@^6.0.0:
Expand Down Expand Up @@ -5806,7 +5765,7 @@ [email protected]:

[email protected], safe-buffer@^5.0.1:
version "5.2.1"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==

safe-regex-test@^1.0.3:
Expand Down Expand Up @@ -6460,7 +6419,7 @@ [email protected]:

uuid@^9.0.1:
version "9.0.1"
resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==

v8-compile-cache-lib@^3.0.1:
Expand Down

0 comments on commit 1308987

Please sign in to comment.