From a9afeecffa24ed1222dd22c6e5ed4e131c5601e5 Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Tue, 27 May 2025 21:07:32 -0700 Subject: [PATCH 01/14] Added Card Reader page to Admin UI - dummy page for now --- src/Components/Navbar/AdminNavbar.js | 9 +++++++++ src/Pages/CardReader/CardReader.js | 7 +++++++ src/Routing.js | 9 +++++++++ 3 files changed, 25 insertions(+) create mode 100644 src/Pages/CardReader/CardReader.js diff --git a/src/Components/Navbar/AdminNavbar.js b/src/Components/Navbar/AdminNavbar.js index 5788d6d1b..67ac7b01a 100644 --- a/src/Components/Navbar/AdminNavbar.js +++ b/src/Components/Navbar/AdminNavbar.js @@ -90,6 +90,15 @@ export default function UserNavBar(props) { ), }, + { + title: 'Card Reader', + route: '/card-reader', + icon: ( + + + + ) + } ]; const renderRoutesForNavbar = (navbarLinks) => { diff --git a/src/Pages/CardReader/CardReader.js b/src/Pages/CardReader/CardReader.js new file mode 100644 index 000000000..a9d873b87 --- /dev/null +++ b/src/Pages/CardReader/CardReader.js @@ -0,0 +1,7 @@ +import { useState } from "react"; + +export default function CardReader() { + return ( +

Welcome to the card reader page!

+ ); +} \ No newline at end of file diff --git a/src/Routing.js b/src/Routing.js index f583a1c48..6bbd4c93a 100644 --- a/src/Routing.js +++ b/src/Routing.js @@ -31,6 +31,8 @@ import EmailPreferencesPage from './Pages/EmailPreferences/EmailPreferences'; import sendUnsubscribeEmail from './Pages/Profile/admin/SendUnsubscribeEmail'; import Messaging from './Pages/Messaging/Messaging.js'; +import CardReader from './Pages/CardReader/CardReader.js'; + export default function Routing({ appProps }) { const userIsAuthenticated = appProps.authenticated; const userIsMember = @@ -138,6 +140,13 @@ export default function Routing({ appProps }) { allowedIf: userIsOfficerOrAdmin, redirect: '/', inAdminNavbar: true + }, + { + Component: CardReader, + path: '/card-reader', + allowedIf: userIsOfficerOrAdmin, + redirect: '/', + inAdminNavbar: true } ]; const signedOutRoutes = [ From a139027144b0aa97a6436626ce0ddfe511c3137f Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Tue, 27 May 2025 21:10:49 -0700 Subject: [PATCH 02/14] syntax fixes --- src/Components/Navbar/AdminNavbar.js | 2 +- src/Routing.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Navbar/AdminNavbar.js b/src/Components/Navbar/AdminNavbar.js index 67ac7b01a..d17387e00 100644 --- a/src/Components/Navbar/AdminNavbar.js +++ b/src/Components/Navbar/AdminNavbar.js @@ -98,7 +98,7 @@ export default function UserNavBar(props) { ) - } + }, ]; const renderRoutesForNavbar = (navbarLinks) => { diff --git a/src/Routing.js b/src/Routing.js index 6bbd4c93a..422db29e1 100644 --- a/src/Routing.js +++ b/src/Routing.js @@ -147,7 +147,7 @@ export default function Routing({ appProps }) { allowedIf: userIsOfficerOrAdmin, redirect: '/', inAdminNavbar: true - } + }, ]; const signedOutRoutes = [ { Component: Home, path: '/' }, From a120bdb85a2069533430ba6bb4890b81e6a1ba4f Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Fri, 30 May 2025 17:30:25 -0700 Subject: [PATCH 03/14] Implement server-sent events to track activity --- api/main_endpoints/routes/OfficeAccessCard.js | 23 +++++++++++++++ src/Pages/CardReader/CardReader.js | 29 +++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/api/main_endpoints/routes/OfficeAccessCard.js b/api/main_endpoints/routes/OfficeAccessCard.js index d91803758..ece47fab8 100644 --- a/api/main_endpoints/routes/OfficeAccessCard.js +++ b/api/main_endpoints/routes/OfficeAccessCard.js @@ -88,4 +88,27 @@ router.get('/verify', async (req, res) =>{ } }); +router.get('/listen', (req, res) => { + res.setHeader('Content-Type', 'text/event-stream'); + res.setHeader('Cache-Control', 'no-cache'); + res.setHeader('Connection', 'keep-alive'); + + // Send an initial message + res.write(`data: Connected to server\n\n`); + + // Simulate sending updates from the server + let counter = 0; + const intervalId = setInterval(() => { + counter++; + // Write the event stream format + res.write(`data: Message ${counter}\n\n`); + }, 2000); + + // When client closes connection, stop sending events + req.on('close', () => { + clearInterval(intervalId); + res.end(); + }); +}); + module.exports = router; diff --git a/src/Pages/CardReader/CardReader.js b/src/Pages/CardReader/CardReader.js index a9d873b87..ed02d9bba 100644 --- a/src/Pages/CardReader/CardReader.js +++ b/src/Pages/CardReader/CardReader.js @@ -1,7 +1,32 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; export default function CardReader() { + + const [logs, setLogs] = useState([]); + + useEffect(() => { + const eventSource = new EventSource("http://localhost:8080/api/OfficeAccessCard/listen"); + eventSource.onmessage = (event) => { + const newLog = new Date().toISOString() + " " + event.data; + setLogs(currLogs => [newLog, ...currLogs]); // prepend the new log + }; + + eventSource.onerror = (event) => { + console.log("Error: ", event); + }; + + return () => { + eventSource.close(); + }; + + }, []); + return ( -

Welcome to the card reader page!

+
+

Welcome to the card reader page!

+
+        {logs.join("\n")}
+      
+
); } \ No newline at end of file From a4f9794e5c8a11bf3de50f2394415577aac698fe Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Tue, 3 Jun 2025 20:20:20 -0700 Subject: [PATCH 04/14] Add API Token verification to /listen endpoint --- api/main_endpoints/routes/OfficeAccessCard.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/api/main_endpoints/routes/OfficeAccessCard.js b/api/main_endpoints/routes/OfficeAccessCard.js index ece47fab8..2bba20c73 100644 --- a/api/main_endpoints/routes/OfficeAccessCard.js +++ b/api/main_endpoints/routes/OfficeAccessCard.js @@ -12,6 +12,10 @@ const OfficeAccessCard = require('../models/OfficeAccessCard.js'); const logger = require('../../util/logger'); const { officeAccessCard = {} } = require('../../config/config.json'); const { API_KEY = 'NOTHING_REALLY' } = officeAccessCard; +const { + decodeToken, + checkIfTokenSent, +} = require('../util/token-functions.js'); router.use(bodyParser.json()); @@ -88,7 +92,14 @@ router.get('/verify', async (req, res) =>{ } }); -router.get('/listen', (req, res) => { +router.get('/listen', async (req, res) => { + + if (!checkIfTokenSent(req)) { + return res.sendStatus(FORBIDDEN); + } else if (!await decodeToken(req)) { + return res.sendStatus(UNAUTHORIZED); + } + res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); From 775f53c2aecd175c790162cf66a51cf64410fc2d Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Thu, 12 Jun 2025 20:26:59 -0700 Subject: [PATCH 05/14] Connect /listen and /verify endpoints --- api/main_endpoints/routes/OfficeAccessCard.js | 74 +++++++++++++------ src/Pages/CardReader/CardReader.js | 3 +- 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/api/main_endpoints/routes/OfficeAccessCard.js b/api/main_endpoints/routes/OfficeAccessCard.js index 2bba20c73..a94023cf0 100644 --- a/api/main_endpoints/routes/OfficeAccessCard.js +++ b/api/main_endpoints/routes/OfficeAccessCard.js @@ -48,6 +48,14 @@ function checkIfCardExists(cardBytes) { }); } +const clients = []; + +const response = { + endpoint: "/verify", + statusCode: 200, + message: "Card authorized!" +} + router.get('/verify', async (req, res) =>{ const { cardBytes, add = false } = req.query; const apiKey = req.headers['x-api-key']; @@ -56,11 +64,18 @@ router.get('/verify', async (req, res) =>{ { value: cardBytes, title: 'cardBytes query parameter', }, ]; + if (add) { + response.endpoint += "?add=1"; + } + const missingValue = required.find(({ value }) => !value); if (missingValue) { + response.statusCode = BAD_REQUEST; + response.message = `${missingValue.title} missing from request`; + writeRequestResponse(); return res.status(BAD_REQUEST).send(` ${missingValue.title} missing from request`); - } + } if (apiKey !== API_KEY) { return res.sendStatus(UNAUTHORIZED); @@ -68,6 +83,7 @@ router.get('/verify', async (req, res) =>{ const cardExists = await checkIfCardExists(cardBytes); if (cardExists) { + writeRequestResponse(); return res.sendStatus(OK); } // if a card doesnt exist and we arent trying @@ -75,6 +91,9 @@ router.get('/verify', async (req, res) =>{ // to verify a card, and that card isnt found. // therefore return a non OK status if (!add) { + response.statusCode = NOT_FOUND; + response.message = "Card not found"; + writeRequestResponse(); return res.sendStatus(NOT_FOUND); } @@ -84,41 +103,48 @@ router.get('/verify', async (req, res) =>{ await new OfficeAccessCard({ cardBytes }).save(); + response.message = "Card added!"; + writeRequestResponse(); return res.sendStatus(OK); } } catch (error) { logger.error('Error creating OfficeAccessCard: ', error); + response.message ="Error creating OfficeAccessCard: " + error; + response.statusCode = SERVER_ERROR; + writeRequestResponse(); return res.sendStatus(SERVER_ERROR); } }); +const writeRequestResponse = () => { + clients.forEach(client => { + client.res.write(`data: ${JSON.stringify(response)}\n\n`); + }) +}; + router.get('/listen', async (req, res) => { - if (!checkIfTokenSent(req)) { - return res.sendStatus(FORBIDDEN); - } else if (!await decodeToken(req)) { - return res.sendStatus(UNAUTHORIZED); - } + // if (!checkIfTokenSent(req)) { + // return res.sendStatus(FORBIDDEN); + // } else if (!await decodeToken(req)) { + // return res.sendStatus(UNAUTHORIZED); + // } - res.setHeader('Content-Type', 'text/event-stream'); - res.setHeader('Cache-Control', 'no-cache'); - res.setHeader('Connection', 'keep-alive'); - - // Send an initial message - res.write(`data: Connected to server\n\n`); - - // Simulate sending updates from the server - let counter = 0; - const intervalId = setInterval(() => { - counter++; - // Write the event stream format - res.write(`data: Message ${counter}\n\n`); - }, 2000); - - // When client closes connection, stop sending events + const headers = { + 'Content-Type': 'text/event-stream', + 'Connection': 'keep-alive', + 'Cache-Control': 'no-cache', + 'X-Accel-Buffering': 'no' + }; + + res.writeHead(200, headers); + + const newClient = { res }; + clients.push(newClient); + req.on('close', () => { - clearInterval(intervalId); - res.end(); + clients = clients.filter(c => c !== newClient); + res.end(); }); }); diff --git a/src/Pages/CardReader/CardReader.js b/src/Pages/CardReader/CardReader.js index ed02d9bba..e78e0bf8d 100644 --- a/src/Pages/CardReader/CardReader.js +++ b/src/Pages/CardReader/CardReader.js @@ -7,7 +7,8 @@ export default function CardReader() { useEffect(() => { const eventSource = new EventSource("http://localhost:8080/api/OfficeAccessCard/listen"); eventSource.onmessage = (event) => { - const newLog = new Date().toISOString() + " " + event.data; + const data = JSON.parse(event.data); + const newLog = new Date().toISOString() + " " + data.endpoint + " " + data.statusCode + " " + data.message; setLogs(currLogs => [newLog, ...currLogs]); // prepend the new log }; From 15cb072d8672479a3cff30f8f3fff0abf7ff0206 Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Thu, 12 Jun 2025 20:58:34 -0700 Subject: [PATCH 06/14] lint fixes --- api/main_endpoints/routes/OfficeAccessCard.js | 29 +++++++++---------- src/Pages/CardReader/CardReader.js | 16 ++++------ 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/api/main_endpoints/routes/OfficeAccessCard.js b/api/main_endpoints/routes/OfficeAccessCard.js index a94023cf0..fafafe818 100644 --- a/api/main_endpoints/routes/OfficeAccessCard.js +++ b/api/main_endpoints/routes/OfficeAccessCard.js @@ -51,10 +51,16 @@ function checkIfCardExists(cardBytes) { const clients = []; const response = { - endpoint: "/verify", + endpoint: '/verify', statusCode: 200, - message: "Card authorized!" -} + message: 'Card authorized!' +}; + +const writeRequestResponse = () => { + clients.forEach(client => { + client.res.write(`data: ${JSON.stringify(response)}\n\n`); + }); +}; router.get('/verify', async (req, res) =>{ const { cardBytes, add = false } = req.query; @@ -65,7 +71,7 @@ router.get('/verify', async (req, res) =>{ ]; if (add) { - response.endpoint += "?add=1"; + response.endpoint += '?add=1'; } const missingValue = required.find(({ value }) => !value); @@ -75,7 +81,7 @@ router.get('/verify', async (req, res) =>{ response.message = `${missingValue.title} missing from request`; writeRequestResponse(); return res.status(BAD_REQUEST).send(` ${missingValue.title} missing from request`); - } + } if (apiKey !== API_KEY) { return res.sendStatus(UNAUTHORIZED); @@ -92,7 +98,7 @@ router.get('/verify', async (req, res) =>{ // therefore return a non OK status if (!add) { response.statusCode = NOT_FOUND; - response.message = "Card not found"; + response.message = 'Card not found'; writeRequestResponse(); return res.sendStatus(NOT_FOUND); } @@ -103,25 +109,19 @@ router.get('/verify', async (req, res) =>{ await new OfficeAccessCard({ cardBytes }).save(); - response.message = "Card added!"; + response.message = 'Card added!'; writeRequestResponse(); return res.sendStatus(OK); } } catch (error) { logger.error('Error creating OfficeAccessCard: ', error); - response.message ="Error creating OfficeAccessCard: " + error; + response.message = 'Error creating OfficeAccessCard: ' + error; response.statusCode = SERVER_ERROR; writeRequestResponse(); return res.sendStatus(SERVER_ERROR); } }); -const writeRequestResponse = () => { - clients.forEach(client => { - client.res.write(`data: ${JSON.stringify(response)}\n\n`); - }) -}; - router.get('/listen', async (req, res) => { // if (!checkIfTokenSent(req)) { @@ -129,7 +129,6 @@ router.get('/listen', async (req, res) => { // } else if (!await decodeToken(req)) { // return res.sendStatus(UNAUTHORIZED); // } - const headers = { 'Content-Type': 'text/event-stream', 'Connection': 'keep-alive', diff --git a/src/Pages/CardReader/CardReader.js b/src/Pages/CardReader/CardReader.js index e78e0bf8d..e09e3841c 100644 --- a/src/Pages/CardReader/CardReader.js +++ b/src/Pages/CardReader/CardReader.js @@ -1,20 +1,16 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect } from 'react'; export default function CardReader() { const [logs, setLogs] = useState([]); - + useEffect(() => { - const eventSource = new EventSource("http://localhost:8080/api/OfficeAccessCard/listen"); + const eventSource = new EventSource('http://localhost:8080/api/OfficeAccessCard/listen'); eventSource.onmessage = (event) => { const data = JSON.parse(event.data); - const newLog = new Date().toISOString() + " " + data.endpoint + " " + data.statusCode + " " + data.message; + const newLog = new Date().toISOString() + ' ' + data.endpoint + ' ' + data.statusCode + ' ' + data.message; setLogs(currLogs => [newLog, ...currLogs]); // prepend the new log }; - - eventSource.onerror = (event) => { - console.log("Error: ", event); - }; return () => { eventSource.close(); @@ -26,8 +22,8 @@ export default function CardReader() {

Welcome to the card reader page!

-        {logs.join("\n")}
+        {logs.join('\n')}
       
); -} \ No newline at end of file +} From f732a01eab8e82a596ece9b905c355575845a687 Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Sun, 15 Jun 2025 19:06:40 -0700 Subject: [PATCH 07/14] Add API token verification to /listen --- api/main_endpoints/routes/OfficeAccessCard.js | 24 ++++++-------- src/Pages/CardReader/CardReader.js | 33 +++++++++++++++---- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/api/main_endpoints/routes/OfficeAccessCard.js b/api/main_endpoints/routes/OfficeAccessCard.js index fafafe818..1d042b234 100644 --- a/api/main_endpoints/routes/OfficeAccessCard.js +++ b/api/main_endpoints/routes/OfficeAccessCard.js @@ -12,10 +12,7 @@ const OfficeAccessCard = require('../models/OfficeAccessCard.js'); const logger = require('../../util/logger'); const { officeAccessCard = {} } = require('../../config/config.json'); const { API_KEY = 'NOTHING_REALLY' } = officeAccessCard; -const { - decodeToken, - checkIfTokenSent, -} = require('../util/token-functions.js'); +const { decodeTokenFromBodyOrQuery } = require('../util/token-functions.js'); router.use(bodyParser.json()); @@ -48,7 +45,7 @@ function checkIfCardExists(cardBytes) { }); } -const clients = []; +let clients = []; const response = { endpoint: '/verify', @@ -70,10 +67,6 @@ router.get('/verify', async (req, res) =>{ { value: cardBytes, title: 'cardBytes query parameter', }, ]; - if (add) { - response.endpoint += '?add=1'; - } - const missingValue = required.find(({ value }) => !value); if (missingValue) { @@ -89,6 +82,7 @@ router.get('/verify', async (req, res) =>{ const cardExists = await checkIfCardExists(cardBytes); if (cardExists) { + response.endpoint = '/verify'; // if user tried to add a card that already existed, ignore the "add" parameter writeRequestResponse(); return res.sendStatus(OK); } @@ -103,6 +97,8 @@ router.get('/verify', async (req, res) =>{ return res.sendStatus(NOT_FOUND); } + response.endpoint = '/verify?add=1'; + try { if (add) { logger.info('adding a new card'); @@ -110,6 +106,7 @@ router.get('/verify', async (req, res) =>{ cardBytes }).save(); response.message = 'Card added!'; + response.statusCode = 200; writeRequestResponse(); return res.sendStatus(OK); } @@ -124,11 +121,10 @@ router.get('/verify', async (req, res) =>{ router.get('/listen', async (req, res) => { - // if (!checkIfTokenSent(req)) { - // return res.sendStatus(FORBIDDEN); - // } else if (!await decodeToken(req)) { - // return res.sendStatus(UNAUTHORIZED); - // } + if (!await decodeTokenFromBodyOrQuery(req)) { + return res.sendStatus(UNAUTHORIZED); + } + const headers = { 'Content-Type': 'text/event-stream', 'Connection': 'keep-alive', diff --git a/src/Pages/CardReader/CardReader.js b/src/Pages/CardReader/CardReader.js index e09e3841c..43b6f9d3a 100644 --- a/src/Pages/CardReader/CardReader.js +++ b/src/Pages/CardReader/CardReader.js @@ -1,17 +1,33 @@ import { useState, useEffect } from 'react'; +import { BASE_API_URL } from '../../Enums'; -export default function CardReader() { - +export default function CardReader(props) { const [logs, setLogs] = useState([]); + const [error, setError] = useState(''); + const token = props.user.token; + + const buildLog = (data) => { + let endpoint = data.endpoint; + if (!endpoint.includes('?add=1')) { + endpoint += ' '; + } + return [new Date().toISOString(), endpoint, data.statusCode, data.message].join(' '); + }; useEffect(() => { - const eventSource = new EventSource('http://localhost:8080/api/OfficeAccessCard/listen'); + const url = new URL('/api/OfficeAccessCard/listen', BASE_API_URL); + url.searchParams.append('token', token); + const eventSource = new EventSource(url.href); eventSource.onmessage = (event) => { - const data = JSON.parse(event.data); - const newLog = new Date().toISOString() + ' ' + data.endpoint + ' ' + data.statusCode + ' ' + data.message; + let data = JSON.parse(event.data); + let newLog = buildLog(data); setLogs(currLogs => [newLog, ...currLogs]); // prepend the new log }; + eventSource.onerror = () => { + setError('Error connecting to SSE'); + } + return () => { eventSource.close(); }; @@ -19,11 +35,14 @@ export default function CardReader() { }, []); return ( -
-

Welcome to the card reader page!

+
+

SCE Card Reader Activity

         {logs.join('\n')}
       
+ {error && +

{error}

+ }
); } From 3a9d1b05a3238e9f83e9ca00fcfb958a7e43a12f Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Sun, 15 Jun 2025 19:07:49 -0700 Subject: [PATCH 08/14] lint fixes --- src/Pages/CardReader/CardReader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pages/CardReader/CardReader.js b/src/Pages/CardReader/CardReader.js index 43b6f9d3a..f76fbceeb 100644 --- a/src/Pages/CardReader/CardReader.js +++ b/src/Pages/CardReader/CardReader.js @@ -26,7 +26,7 @@ export default function CardReader(props) { eventSource.onerror = () => { setError('Error connecting to SSE'); - } + }; return () => { eventSource.close(); @@ -40,7 +40,7 @@ export default function CardReader(props) {
         {logs.join('\n')}
       
- {error && + {error &&

{error}

}
From 1d0faf94c78a63b4c785ae4e66c91f5cc78a0731 Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Mon, 16 Jun 2025 16:36:54 -0700 Subject: [PATCH 09/14] Fixed scope of request response --- api/main_endpoints/routes/OfficeAccessCard.js | 39 +++++++------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/api/main_endpoints/routes/OfficeAccessCard.js b/api/main_endpoints/routes/OfficeAccessCard.js index 1d042b234..84bf2e4f6 100644 --- a/api/main_endpoints/routes/OfficeAccessCard.js +++ b/api/main_endpoints/routes/OfficeAccessCard.js @@ -47,13 +47,14 @@ function checkIfCardExists(cardBytes) { let clients = []; -const response = { - endpoint: '/verify', - statusCode: 200, - message: 'Card authorized!' -}; - -const writeRequestResponse = () => { +const writeRequestResponse = (endpoint, statusCode, message) => { + console.log('reached inside writeRequestResponse'); + response = { + endpoint: endpoint, + statusCode: statusCode, + message: message, + }; + console.log('now sending to clients'); clients.forEach(client => { client.res.write(`data: ${JSON.stringify(response)}\n\n`); }); @@ -70,9 +71,7 @@ router.get('/verify', async (req, res) =>{ const missingValue = required.find(({ value }) => !value); if (missingValue) { - response.statusCode = BAD_REQUEST; - response.message = `${missingValue.title} missing from request`; - writeRequestResponse(); + writeRequestResponse('/verify', BAD_REQUEST, `${missingValue.title} missing from request`); return res.status(BAD_REQUEST).send(` ${missingValue.title} missing from request`); } @@ -82,8 +81,7 @@ router.get('/verify', async (req, res) =>{ const cardExists = await checkIfCardExists(cardBytes); if (cardExists) { - response.endpoint = '/verify'; // if user tried to add a card that already existed, ignore the "add" parameter - writeRequestResponse(); + writeRequestResponse('/verify', OK, 'Card authorized!'); return res.sendStatus(OK); } // if a card doesnt exist and we arent trying @@ -91,36 +89,27 @@ router.get('/verify', async (req, res) =>{ // to verify a card, and that card isnt found. // therefore return a non OK status if (!add) { - response.statusCode = NOT_FOUND; - response.message = 'Card not found'; - writeRequestResponse(); + writeRequestResponse('/verify', NOT_FOUND, 'Card not found'); return res.sendStatus(NOT_FOUND); } - response.endpoint = '/verify?add=1'; - try { if (add) { logger.info('adding a new card'); await new OfficeAccessCard({ cardBytes }).save(); - response.message = 'Card added!'; - response.statusCode = 200; - writeRequestResponse(); + writeRequestResponse('/verify?add=1', OK, 'Card added!'); return res.sendStatus(OK); } } catch (error) { logger.error('Error creating OfficeAccessCard: ', error); - response.message = 'Error creating OfficeAccessCard: ' + error; - response.statusCode = SERVER_ERROR; - writeRequestResponse(); + writeRequestResponse('/verify?add=1', SERVER_ERROR, `Error creating Office AccessCard: ${error}`); return res.sendStatus(SERVER_ERROR); } }); router.get('/listen', async (req, res) => { - if (!await decodeTokenFromBodyOrQuery(req)) { return res.sendStatus(UNAUTHORIZED); } @@ -132,7 +121,7 @@ router.get('/listen', async (req, res) => { 'X-Accel-Buffering': 'no' }; - res.writeHead(200, headers); + res.writeHead(OK, headers); const newClient = { res }; clients.push(newClient); From f087c18abbc56f2a56d2894b725f159f77115b70 Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Mon, 16 Jun 2025 16:37:46 -0700 Subject: [PATCH 10/14] lint fixes --- api/main_endpoints/routes/OfficeAccessCard.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/main_endpoints/routes/OfficeAccessCard.js b/api/main_endpoints/routes/OfficeAccessCard.js index 84bf2e4f6..dafed6b07 100644 --- a/api/main_endpoints/routes/OfficeAccessCard.js +++ b/api/main_endpoints/routes/OfficeAccessCard.js @@ -48,13 +48,11 @@ function checkIfCardExists(cardBytes) { let clients = []; const writeRequestResponse = (endpoint, statusCode, message) => { - console.log('reached inside writeRequestResponse'); response = { endpoint: endpoint, statusCode: statusCode, message: message, }; - console.log('now sending to clients'); clients.forEach(client => { client.res.write(`data: ${JSON.stringify(response)}\n\n`); }); From b124673b7fac3f8a47e76735840793c41f78e151 Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Wed, 18 Jun 2025 21:57:08 -0700 Subject: [PATCH 11/14] Fixed structure of response body --- api/main_endpoints/routes/OfficeAccessCard.js | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/api/main_endpoints/routes/OfficeAccessCard.js b/api/main_endpoints/routes/OfficeAccessCard.js index dafed6b07..daa6e6ac7 100644 --- a/api/main_endpoints/routes/OfficeAccessCard.js +++ b/api/main_endpoints/routes/OfficeAccessCard.js @@ -47,11 +47,17 @@ function checkIfCardExists(cardBytes) { let clients = []; -const writeRequestResponse = (endpoint, statusCode, message) => { - response = { - endpoint: endpoint, - statusCode: statusCode, - message: message, +const defaultResponse = { + cardWasAdded: false, + message: 'Card authorized!', + endpoint: '/verify', +}; + +const writeRequestResponse = ({ statusCode, ...rest }) => { + const response = { + statusCode, + ...defaultResponse, + ...rest, }; clients.forEach(client => { client.res.write(`data: ${JSON.stringify(response)}\n\n`); @@ -69,7 +75,7 @@ router.get('/verify', async (req, res) =>{ const missingValue = required.find(({ value }) => !value); if (missingValue) { - writeRequestResponse('/verify', BAD_REQUEST, `${missingValue.title} missing from request`); + writeRequestResponse({ statusCode: BAD_REQUEST, message: `${missingValue.title} missing from request` }); return res.status(BAD_REQUEST).send(` ${missingValue.title} missing from request`); } @@ -79,7 +85,7 @@ router.get('/verify', async (req, res) =>{ const cardExists = await checkIfCardExists(cardBytes); if (cardExists) { - writeRequestResponse('/verify', OK, 'Card authorized!'); + writeRequestResponse({ statusCode: OK }); return res.sendStatus(OK); } // if a card doesnt exist and we arent trying @@ -87,7 +93,7 @@ router.get('/verify', async (req, res) =>{ // to verify a card, and that card isnt found. // therefore return a non OK status if (!add) { - writeRequestResponse('/verify', NOT_FOUND, 'Card not found'); + writeRequestResponse({ statusCode: NOT_FOUND, message: 'Card not found' }); return res.sendStatus(NOT_FOUND); } @@ -97,12 +103,16 @@ router.get('/verify', async (req, res) =>{ await new OfficeAccessCard({ cardBytes }).save(); - writeRequestResponse('/verify?add=1', OK, 'Card added!'); + writeRequestResponse({ statusCode: OK, message: 'Card added!', endpoint: '/verify?add=1' }); return res.sendStatus(OK); } } catch (error) { logger.error('Error creating OfficeAccessCard: ', error); - writeRequestResponse('/verify?add=1', SERVER_ERROR, `Error creating Office AccessCard: ${error}`); + writeRequestResponse({ + statusCode: SERVER_ERROR, + endpoint: '/verify?add=1', + message: `Error creating Office AccessCard: ${error}` + }); return res.sendStatus(SERVER_ERROR); } }); From 77c9c858744e40f0d0457e6bd8fd26372d061d65 Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Wed, 18 Jun 2025 21:58:04 -0700 Subject: [PATCH 12/14] lint fixes --- api/main_endpoints/routes/OfficeAccessCard.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/main_endpoints/routes/OfficeAccessCard.js b/api/main_endpoints/routes/OfficeAccessCard.js index daa6e6ac7..97789da05 100644 --- a/api/main_endpoints/routes/OfficeAccessCard.js +++ b/api/main_endpoints/routes/OfficeAccessCard.js @@ -109,9 +109,9 @@ router.get('/verify', async (req, res) =>{ } catch (error) { logger.error('Error creating OfficeAccessCard: ', error); writeRequestResponse({ - statusCode: SERVER_ERROR, - endpoint: '/verify?add=1', - message: `Error creating Office AccessCard: ${error}` + statusCode: SERVER_ERROR, + endpoint: '/verify?add=1', + message: `Error creating Office AccessCard: ${error}` }); return res.sendStatus(SERVER_ERROR); } From 4ce35cdf7980e0da7b1a784ead9f9d16d13f7728 Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Thu, 19 Jun 2025 11:18:34 -0700 Subject: [PATCH 13/14] add try/catch for data parsing --- src/Pages/CardReader/CardReader.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Pages/CardReader/CardReader.js b/src/Pages/CardReader/CardReader.js index f76fbceeb..b0877bb4d 100644 --- a/src/Pages/CardReader/CardReader.js +++ b/src/Pages/CardReader/CardReader.js @@ -7,11 +7,10 @@ export default function CardReader(props) { const token = props.user.token; const buildLog = (data) => { - let endpoint = data.endpoint; - if (!endpoint.includes('?add=1')) { - endpoint += ' '; - } - return [new Date().toISOString(), endpoint, data.statusCode, data.message].join(' '); + let date = new Date().toISOString().padEnd(30, ' '); + let endpoint = data.endpoint.padEnd(20, ' '); + let statusCode = String(data.statusCode).padEnd(8, ' '); + return [date, endpoint, statusCode, data.message].join(''); }; useEffect(() => { @@ -19,9 +18,19 @@ export default function CardReader(props) { url.searchParams.append('token', token); const eventSource = new EventSource(url.href); eventSource.onmessage = (event) => { - let data = JSON.parse(event.data); - let newLog = buildLog(data); - setLogs(currLogs => [newLog, ...currLogs]); // prepend the new log + try { + let data = JSON.parse(event.data); + let newLog = buildLog(data); + setLogs(currLogs => [newLog, ...currLogs]); // prepend the new log + } catch (error) { + console.error('unable to format event data from /listen', error); + setLogs( + (currLogs) => [ + '[error] unable to format response, check browser logs', + ...currLogs, + ] + ); + } }; eventSource.onerror = () => { From 7c07f78ca1092284adbb0070f5bc392cd3326dcd Mon Sep 17 00:00:00 2001 From: adarshm11 Date: Thu, 19 Jun 2025 11:19:44 -0700 Subject: [PATCH 14/14] removed console log --- src/Pages/CardReader/CardReader.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Pages/CardReader/CardReader.js b/src/Pages/CardReader/CardReader.js index b0877bb4d..8f66eb6d0 100644 --- a/src/Pages/CardReader/CardReader.js +++ b/src/Pages/CardReader/CardReader.js @@ -23,7 +23,6 @@ export default function CardReader(props) { let newLog = buildLog(data); setLogs(currLogs => [newLog, ...currLogs]); // prepend the new log } catch (error) { - console.error('unable to format event data from /listen', error); setLogs( (currLogs) => [ '[error] unable to format response, check browser logs',