From 378720b235789f30723f61e8f934bbc0a7e08666 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Sat, 27 Sep 2025 16:37:57 +0200 Subject: [PATCH 1/4] created APIKeyTable --- admin/src/Layout/Dashboard.tsx | 3 + admin/src/Layout/Sidebar.tsx | 11 ++ admin/src/components/APIKeyTable.tsx | 211 +++++++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 admin/src/components/APIKeyTable.tsx diff --git a/admin/src/Layout/Dashboard.tsx b/admin/src/Layout/Dashboard.tsx index 7d78cdf..1b53d6d 100644 --- a/admin/src/Layout/Dashboard.tsx +++ b/admin/src/Layout/Dashboard.tsx @@ -5,6 +5,7 @@ import Sidebar from "./Sidebar"; import UserTable from "../components/UserTable"; import ItemTable from "../components/ItemTable"; import LoanTable from "../components/LoanTable"; +import APIKeyTable from "@/components/APIKeyTable"; import { MoveLeft } from "lucide-react"; type DashboardProps = { @@ -23,6 +24,7 @@ const Dashboard: React.FC = ({ onLogout }) => { viewGegenstaende={() => setActiveView("Gegenstände")} viewSchliessfaecher={() => setActiveView("Schließfächer")} viewUser={() => setActiveView("User")} + viewAPI={() => setActiveView("API")} /> = ({ onLogout }) => { {activeView === "User" && } {activeView === "Ausleihen" && } {activeView === "Gegenstände" && } + {activeView === "API" && } diff --git a/admin/src/Layout/Sidebar.tsx b/admin/src/Layout/Sidebar.tsx index 3637124..05817fe 100644 --- a/admin/src/Layout/Sidebar.tsx +++ b/admin/src/Layout/Sidebar.tsx @@ -6,12 +6,14 @@ type SidebarProps = { viewGegenstaende: () => void; viewSchliessfaecher: () => void; viewUser: () => void; + viewAPI: () => void; }; const Sidebar: React.FC = ({ viewAusleihen, viewGegenstaende, viewUser, + viewAPI, }) => { return ( = ({ > Gegenstände + + API Keys + diff --git a/admin/src/components/APIKeyTable.tsx b/admin/src/components/APIKeyTable.tsx new file mode 100644 index 0000000..ab97718 --- /dev/null +++ b/admin/src/components/APIKeyTable.tsx @@ -0,0 +1,211 @@ +import React from "react"; +import { + Table, + Spinner, + Text, + VStack, + Button, + HStack, + IconButton, + Heading, +} from "@chakra-ui/react"; +import { Tooltip } from "@/components/ui/tooltip"; +import MyAlert from "./myChakra/MyAlert"; +import { + Trash2, + RefreshCcwDot, + CirclePlus, +} from "lucide-react"; +import Cookies from "js-cookie"; +import { useState, useEffect } from "react"; +import { + deleteItem, +} from "@/utils/userActions"; +import AddItemForm from "./AddItemForm"; +import { formatDateTime } from "@/utils/userFuncs"; + +type Items = { + id: number; + apiKey: string; + user: string; + entry_created_at: string; +}; + +const APIKeyTable: React.FC = () => { + const [items, setItems] = useState([]); + const [errorStatus, setErrorStatus] = useState<"error" | "success">("error"); + const [errorMessage, setErrorMessage] = useState(""); + const [errorDsc, setErrorDsc] = useState(""); + const [isError, setIsError] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [reload, setReload] = useState(false); + const [addAPIForm, setAddAPIForm] = useState(false); + + const setError = ( + status: "error" | "success", + message: string, + description: string + ) => { + setIsError(false); + setErrorStatus(status); + setErrorMessage(message); + setErrorDsc(description); + setIsError(true); + }; + + useEffect(() => { + const fetchData = async () => { + setIsLoading(true); + try { + const response = await fetch("http://localhost:8002/api/keys", { + method: "GET", + headers: { + Authorization: `Bearer ${Cookies.get("token")}`, + }, + }); + const data = await response.json(); + return data; + } catch (error) { + setError("error", "Failed to fetch items", "There is an error"); + } finally { + setIsLoading(false); + } + }; + fetchData().then((data) => { + if (Array.isArray(data)) { + setItems(data); + } + }); + }, [reload]); + + return ( + <> + {/* Action toolbar */} + + + setReload(!reload)} + > + + + + + + + + + {/* End action toolbar */} + + + Gegenstände + + {isError && ( + + )} + {isLoading && ( + + + Loading... + + )} + {addAPIForm && ( + { + setAddAPIForm(false); + setReload(!reload); + }} + alert={setError} + /> + )} + + + + + + # + + + API Key + + + Benutzer + + + Eintrag erstellt am + + + Aktionen + + + + + {items.map((apiKey) => ( + + {apiKey.id} + {apiKey.apiKey} + + {apiKey.user} + + {formatDateTime(apiKey.entry_created_at)} + + + + + ))} + + + + ); +}; + +export default APIKeyTable; From b9d637665cd1e902747cdf178fe99e22860cb94d Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Sat, 27 Sep 2025 16:40:36 +0200 Subject: [PATCH 2/4] changed data scheme --- backend/scheme.sql | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/backend/scheme.sql b/backend/scheme.sql index c7b368b..505c1b6 100644 --- a/backend/scheme.sql +++ b/backend/scheme.sql @@ -58,6 +58,15 @@ CREATE TABLE `lockers` ( UNIQUE KEY `locker_number` (`locker_number`) ); +CREATE TABLE `apiKeys` ( + `id` int NOT NULL AUTO_INCREMENT, + `apiKey` int NOT NULL UNIQUE, + `user` VARCHAR(255) NOT NULL, + `entry_created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `apiKey` (`apiKey`) +); + INSERT INTO `items` (`item_name`, `can_borrow_role`, `inSafe`) VALUES ('DJI 1er Mikro', 4, 1), ('DJI 2er Mikro 1', 4, 1), From f83f321876a49529e4a08d7675dc379859e4ca02 Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Sat, 27 Sep 2025 17:33:59 +0200 Subject: [PATCH 3/4] NOT WORKING - Implement API key management features: add API key creation and deletion, update API routes, and refactor related components. - NOT WORKING --- admin/src/components/APIKeyTable.tsx | 24 ++---- admin/src/components/AddAPIKey.tsx | 73 +++++++++++++++++ admin/src/utils/userActions.ts | 41 ++++++++++ backend/routes/api.js | 76 +++++++++++++++++ backend/routes/apiV2.js | 117 ++++++++++++++++----------- backend/services/database.js | 33 ++++++++ 6 files changed, 299 insertions(+), 65 deletions(-) create mode 100644 admin/src/components/AddAPIKey.tsx diff --git a/admin/src/components/APIKeyTable.tsx b/admin/src/components/APIKeyTable.tsx index ab97718..2173ce3 100644 --- a/admin/src/components/APIKeyTable.tsx +++ b/admin/src/components/APIKeyTable.tsx @@ -11,17 +11,11 @@ import { } from "@chakra-ui/react"; import { Tooltip } from "@/components/ui/tooltip"; import MyAlert from "./myChakra/MyAlert"; -import { - Trash2, - RefreshCcwDot, - CirclePlus, -} from "lucide-react"; +import { Trash2, RefreshCcwDot, CirclePlus } from "lucide-react"; import Cookies from "js-cookie"; import { useState, useEffect } from "react"; -import { - deleteItem, -} from "@/utils/userActions"; -import AddItemForm from "./AddItemForm"; +import { deleteAPKey } from "@/utils/userActions"; +import AddAPIKey from "./AddAPIKey"; import { formatDateTime } from "@/utils/userFuncs"; type Items = { @@ -57,7 +51,7 @@ const APIKeyTable: React.FC = () => { const fetchData = async () => { setIsLoading(true); try { - const response = await fetch("http://localhost:8002/api/keys", { + const response = await fetch("http://localhost:8002/api/apiKeys", { method: "GET", headers: { Authorization: `Bearer ${Cookies.get("token")}`, @@ -118,7 +112,7 @@ const APIKeyTable: React.FC = () => { }} > - Neuen Gegenstand hinzufügen + Neuen API Key hinzufügen @@ -141,7 +135,7 @@ const APIKeyTable: React.FC = () => { )} {addAPIForm && ( - { setAddAPIForm(false); setReload(!reload); @@ -175,14 +169,12 @@ const APIKeyTable: React.FC = () => { {apiKey.id} {apiKey.apiKey} - - {apiKey.user} - + {apiKey.user} {formatDateTime(apiKey.entry_created_at)} + + + + + ); +}; + +export default AddAPIKey; diff --git a/admin/src/utils/userActions.ts b/admin/src/utils/userActions.ts index beac000..8cf8e1e 100644 --- a/admin/src/utils/userActions.ts +++ b/admin/src/utils/userActions.ts @@ -201,3 +201,44 @@ export const changeSafeState = async (itemId: number) => { return { success: false }; } }; + +export const createAPIentry = async (apiKey: string, user: string) => { + try { + const response = await fetch(`http://localhost:8002/api/createAPIentry`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${Cookies.get("token")}`, + }, + body: JSON.stringify({ apiKey, user }), + }); + if (!response.ok) { + throw new Error("Failed to create API entry"); + } + return { success: true }; + } catch (error) { + console.error("Error creating API entry:", error); + return { success: false }; + } +}; + +export const deleteAPKey = async (apiKeyId: number) => { + try { + const response = await fetch( + `http://localhost:8002/api/deleteAPKey/${apiKeyId}`, + { + method: "DELETE", + headers: { + Authorization: `Bearer ${Cookies.get("token")}`, + }, + } + ); + if (!response.ok) { + throw new Error("Failed to delete API key"); + } + return { success: true }; + } catch (error) { + console.error("Error deleting API key:", error); + return { success: false }; + } +}; diff --git a/backend/routes/api.js b/backend/routes/api.js index 2b08eed..4b35f53 100644 --- a/backend/routes/api.js +++ b/backend/routes/api.js @@ -22,6 +22,9 @@ import { changeUserPasswordFRONTEND, changeInSafeStateV2, updateItemByID, + getAllApiKeys, + createAPIentry, + deleteAPKey, } from "../services/database.js"; import { authenticate, generateToken } from "../services/tokenService.js"; const router = express.Router(); @@ -330,4 +333,77 @@ router.put("/changeSafeState/:itemId", authenticate, async (req, res) => { return res.status(500).json({ message: "Failed to update item safe state" }); }); +router.get("/apiKeys", authenticate, async (req, res) => { + const result = await getAllApiKeys(); + if (result.success) { + return res.status(200).json(result.data); + } + return res.status(500).json({ message: "Failed to fetch API keys" }); +}); + +router.get("/apiKeys/apiV2/:id", authenticate, async (req, res) => { + if (req.params.id !== process.env.ADMIN_ID) { + return res.status(403).json({ message: "Access denied" }); + } + const result = await getAPIkey(); + if (result.success) { + return res.status(200).json(result.data); + } + return res.status(500).json({ message: "Failed to fetch API keys" }); +}); + +router.delete("/deleteAPKey/:id", authenticate, async (req, res) => { + const apiKeyId = req.params.id; + const result = await deleteAPKey(apiKeyId); + if (result.success) { + return res.status(200).json({ message: "API key deleted successfully" }); + } + return res.status(500).json({ message: "Failed to delete API key" }); +}); + +router.post("/createAPIentry", authenticate, async (req, res) => { + const apiKey = req.body.apiKey; + const user = req.body.user; + if (!apiKey || !user) { + return res.status(400).json({ message: "API key and user are required" }); + } + + // Ensure apiKey is a number + const apiKeyNum = Number(apiKey); + if (!Number.isFinite(apiKeyNum)) { + return res.status(400).json({ message: "API key must be a number" }); + } + + const result = await createAPIentry(apiKeyNum, user); + if (result.success) { + return res.status(201).json({ message: "API key created successfully" }); + } + if (result.code === "DUPLICATE") { + return res.status(409).json({ message: "API key already exists" }); + } + return res.status(500).json({ message: "Failed to create API key" }); +}); + +router.get("/apiKeys/validate/:key", async (req, res) => { + try { + const rawKey = req.params.key; + const result = await getAllApiKeys(); + if (!result.success || !Array.isArray(result.data)) { + return res.status(500).json({ valid: false }); + } + + const isValid = result.data.some((entry) => { + const val = String( + entry?.key ?? entry?.apiKey ?? entry?.api_key ?? entry + ); + return val === String(rawKey); + }); + + return res.status(200).json({ valid: isValid }); + } catch (err) { + console.error("validate api key error:", err); + return res.status(500).json({ valid: false }); + } +}); + export default router; diff --git a/backend/routes/apiV2.js b/backend/routes/apiV2.js index b43c02e..bf78ea7 100644 --- a/backend/routes/apiV2.js +++ b/backend/routes/apiV2.js @@ -7,93 +7,110 @@ import { setTakeDateV2, getLoanByCodeV2, getAllLoansV2, + getAPIkey, } from "../services/database.js"; dotenv.config(); const router = express.Router(); +async function validateAPIKey(apiKey) { + try { + const result = await getAPIkey(); + if (!result.success || !Array.isArray(result.data)) return false; + + return result.data.some((row) => { + const val = String(row?.apiKey ?? row?.key ?? row?.api_key); + return val === String(apiKey); + }); + } catch (err) { + console.error("validateAPIKey error:", err); + return false; + } +} + +async function ensureValidApiKey(req, res) { + const isValid = await validateAPIKey(req.params.key); + if (!isValid) { + res.status(403).json({ message: "Access denied" }); + return false; + } + return true; +} + // Route for API to get ALL items from the database router.get("/items/:key", async (req, res) => { - if (req.params.key === process.env.ADMIN_ID) { - const result = await getItemsFromDatabaseV2(); - if (result.success) { - res.status(200).json({ data: result.data }); - } else { - res.status(500).json({ message: "Failed to fetch items" }); - } + if (!(await ensureValidApiKey(req, res))) return; + + const result = await getItemsFromDatabaseV2(); + if (result.success) { + res.status(200).json({ data: result.data }); } else { - res.status(403).json({ message: "Access denied" }); + res.status(500).json({ message: "Failed to fetch items" }); } }); // Route for API to control the position of an item router.post("/controlInSafe/:key/:itemId/:state", async (req, res) => { - if (req.params.key === process.env.ADMIN_ID) { - const itemId = req.params.itemId; - const state = req.params.state; - if (state === "1" || state === "0") { - const result = await changeInSafeStateV2(itemId, state); - if (result.success) { - res.status(200).json({ data: result.data }); - } else { - res.status(500).json({ message: "Failed to update item state" }); - } + if (!(await ensureValidApiKey(req, res))) return; + + const itemId = req.params.itemId; + const state = req.params.state; + + if (state === "1" || state === "0") { + const result = await changeInSafeStateV2(itemId, state); + if (result.success) { + res.status(200).json({ data: result.data }); } else { - res.status(400).json({ message: "Invalid state value" }); + res.status(500).json({ message: "Failed to update item state" }); } } else { - res.status(403).json({ message: "Access denied" }); + res.status(400).json({ message: "Invalid state value" }); } }); // Route for API to get a loan by its code router.get("/getLoanByCode/:key/:loan_code", async (req, res) => { - if (req.params.key === process.env.ADMIN_ID) { - const loan_code = req.params.loan_code; + if (!(await ensureValidApiKey(req, res))) return; - const result = await getLoanByCodeV2(loan_code); - if (result.success) { - res.status(200).json({ data: result.data }); - } else { - res.status(404).json({ message: "Loan not found" }); - } + const loan_code = req.params.loan_code; + const result = await getLoanByCodeV2(loan_code); + if (result.success) { + res.status(200).json({ data: result.data }); + } else { + res.status(404).json({ message: "Loan not found" }); } }); // Route for API to set the return date by the loan code router.post("/setReturnDate/:key/:loan_code", async (req, res) => { - if (req.params.key === process.env.ADMIN_ID) { - const loanCode = req.params.loan_code; + if (!(await ensureValidApiKey(req, res))) return; - const result = await setReturnDateV2(loanCode); - if (result.success) { - res.status(200).json({ data: result.data }); - } else { - res.status(500).json({ message: "Failed to set return date" }); - } + const loanCode = req.params.loan_code; + const result = await setReturnDateV2(loanCode); + if (result.success) { + res.status(200).json({ data: result.data }); } else { - res.status(403).json({ message: "Access denied" }); + res.status(500).json({ message: "Failed to set return date" }); } }); // Route for API to set the take away date by the loan code router.post("/setTakeDate/:key/:loan_code", async (req, res) => { - if (req.params.key === process.env.ADMIN_ID) { - const loanCode = req.params.loan_code; + if (!(await ensureValidApiKey(req, res))) return; - const result = await setTakeDateV2(loanCode); - if (result.success) { - res.status(200).json({ data: result.data }); - } else { - res.status(500).json({ message: "Failed to set take date" }); - } + const loanCode = req.params.loan_code; + const result = await setTakeDateV2(loanCode); + if (result.success) { + res.status(200).json({ data: result.data }); } else { - res.status(403).json({ message: "Access denied" }); + res.status(500).json({ message: "Failed to set take date" }); } }); // Route for API to get ALL loans from the database without sensitive info -router.get("/allLoans", async (req, res) => { +router.get("/allLoans/:key", async (req, res) => { + if (!(await ensureValidApiKey(req, res))) return; + const result = await getAllLoansV2(); if (result.success) { return res.status(200).json(result.data); @@ -101,8 +118,10 @@ router.get("/allLoans", async (req, res) => { return res.status(500).json({ message: "Failed to fetch loans" }); }); -// Route for API to get ALL items form the database without key -router.get("/allItems", async (req, res) => { +// Route for API to get ALL items form the database +router.get("/allItems/:key", async (req, res) => { + if (!(await ensureValidApiKey(req, res))) return; + const result = await getItemsFromDatabaseV2(); if (result.success) { res.status(200).json(result.data); diff --git a/backend/services/database.js b/backend/services/database.js index 4e1492a..5ddcc9c 100644 --- a/backend/services/database.js +++ b/backend/services/database.js @@ -457,3 +457,36 @@ export const getAllLoansV2 = async () => { } return { success: false }; }; + +export const getAllApiKeys = async () => { + const [rows] = await pool.query("SELECT * FROM apiKeys"); + if (rows.length > 0) { + return { success: true, data: rows }; + } + return { success: false }; +}; + +export const createAPIentry = async (apiKey, user) => { + const [result] = await pool.query( + "INSERT INTO apiKeys (apiKey, user) VALUES (?, ?)", + [apiKey, user] + ); + if (result.affectedRows > 0) return { success: true }; + return { success: false }; +}; + +export const deleteAPKey = async (apiKeyId) => { + const [result] = await pool.query("DELETE FROM apiKeys WHERE id = ?", [ + apiKeyId, + ]); + if (result.affectedRows > 0) return { success: true }; + return { success: false }; +}; + +export const getAPIkey = async () => { + const [rows] = await pool.query("SELECT apiKey FROM apiKeys"); + if (rows.length > 0) { + return { success: true, data: rows }; + } + return { success: false }; +}; From 0fca896cc21b7c946e5d43284c33c51c2ead87fe Mon Sep 17 00:00:00 2001 From: Theis Gaedigk Date: Sat, 27 Sep 2025 22:54:15 +0200 Subject: [PATCH 4/4] Refactor API key validation: streamline error handling and enforce API key presence in routes --- backend/routes/api.js | 11 ------ backend/routes/apiV2.js | 88 ++++++++++++++++++++--------------------- 2 files changed, 44 insertions(+), 55 deletions(-) diff --git a/backend/routes/api.js b/backend/routes/api.js index 4b35f53..05c6536 100644 --- a/backend/routes/api.js +++ b/backend/routes/api.js @@ -341,17 +341,6 @@ router.get("/apiKeys", authenticate, async (req, res) => { return res.status(500).json({ message: "Failed to fetch API keys" }); }); -router.get("/apiKeys/apiV2/:id", authenticate, async (req, res) => { - if (req.params.id !== process.env.ADMIN_ID) { - return res.status(403).json({ message: "Access denied" }); - } - const result = await getAPIkey(); - if (result.success) { - return res.status(200).json(result.data); - } - return res.status(500).json({ message: "Failed to fetch API keys" }); -}); - router.delete("/deleteAPKey/:id", authenticate, async (req, res) => { const apiKeyId = req.params.id; const result = await deleteAPKey(apiKeyId); diff --git a/backend/routes/apiV2.js b/backend/routes/apiV2.js index bf78ea7..15f994d 100644 --- a/backend/routes/apiV2.js +++ b/backend/routes/apiV2.js @@ -15,32 +15,40 @@ const router = express.Router(); async function validateAPIKey(apiKey) { try { + if (!apiKey) return false; const result = await getAPIkey(); - if (!result.success || !Array.isArray(result.data)) return false; - - return result.data.some((row) => { - const val = String(row?.apiKey ?? row?.key ?? row?.api_key); - return val === String(apiKey); - }); + if (!result?.success || !Array.isArray(result.data)) return false; + return result.data.some((row) => String(row.apiKey) === String(apiKey)); } catch (err) { console.error("validateAPIKey error:", err); return false; } } -async function ensureValidApiKey(req, res) { - const isValid = await validateAPIKey(req.params.key); - if (!isValid) { - res.status(403).json({ message: "Access denied" }); - return false; +// Add a guard that returns Access Denied instead of hanging +const apiKeyGuard = async (req, res, next) => { + try { + const key = req.params.key; + if (!key) { + return res + .status(401) + .json({ message: "Access denied: missing API key" }); + } + const ok = await validateAPIKey(key); + if (!ok) { + return res + .status(401) + .json({ message: "Access denied: invalid API key" }); + } + next(); + } catch (e) { + console.error("apiKeyGuard error:", e); + res.status(500).json({ message: "Internal server error" }); } - return true; -} +}; // Route for API to get ALL items from the database -router.get("/items/:key", async (req, res) => { - if (!(await ensureValidApiKey(req, res))) return; - +router.get("/items/:key", apiKeyGuard, async (req, res) => { const result = await getItemsFromDatabaseV2(); if (result.success) { res.status(200).json({ data: result.data }); @@ -50,28 +58,28 @@ router.get("/items/:key", async (req, res) => { }); // Route for API to control the position of an item -router.post("/controlInSafe/:key/:itemId/:state", async (req, res) => { - if (!(await ensureValidApiKey(req, res))) return; +router.post( + "/controlInSafe/:key/:itemId/:state", + apiKeyGuard, + async (req, res) => { + const itemId = req.params.itemId; + const state = req.params.state; - const itemId = req.params.itemId; - const state = req.params.state; - - if (state === "1" || state === "0") { - const result = await changeInSafeStateV2(itemId, state); - if (result.success) { - res.status(200).json({ data: result.data }); + if (state === "1" || state === "0") { + const result = await changeInSafeStateV2(itemId, state); + if (result.success) { + res.status(200).json({ data: result.data }); + } else { + res.status(500).json({ message: "Failed to update item state" }); + } } else { - res.status(500).json({ message: "Failed to update item state" }); + res.status(400).json({ message: "Invalid state value" }); } - } else { - res.status(400).json({ message: "Invalid state value" }); } -}); +); // Route for API to get a loan by its code -router.get("/getLoanByCode/:key/:loan_code", async (req, res) => { - if (!(await ensureValidApiKey(req, res))) return; - +router.get("/getLoanByCode/:key/:loan_code", apiKeyGuard, async (req, res) => { const loan_code = req.params.loan_code; const result = await getLoanByCodeV2(loan_code); if (result.success) { @@ -82,9 +90,7 @@ router.get("/getLoanByCode/:key/:loan_code", async (req, res) => { }); // Route for API to set the return date by the loan code -router.post("/setReturnDate/:key/:loan_code", async (req, res) => { - if (!(await ensureValidApiKey(req, res))) return; - +router.post("/setReturnDate/:key/:loan_code", apiKeyGuard, async (req, res) => { const loanCode = req.params.loan_code; const result = await setReturnDateV2(loanCode); if (result.success) { @@ -95,9 +101,7 @@ router.post("/setReturnDate/:key/:loan_code", async (req, res) => { }); // Route for API to set the take away date by the loan code -router.post("/setTakeDate/:key/:loan_code", async (req, res) => { - if (!(await ensureValidApiKey(req, res))) return; - +router.post("/setTakeDate/:key/:loan_code", apiKeyGuard, async (req, res) => { const loanCode = req.params.loan_code; const result = await setTakeDateV2(loanCode); if (result.success) { @@ -108,9 +112,7 @@ router.post("/setTakeDate/:key/:loan_code", async (req, res) => { }); // Route for API to get ALL loans from the database without sensitive info -router.get("/allLoans/:key", async (req, res) => { - if (!(await ensureValidApiKey(req, res))) return; - +router.get("/allLoans/:key", apiKeyGuard, async (req, res) => { const result = await getAllLoansV2(); if (result.success) { return res.status(200).json(result.data); @@ -119,9 +121,7 @@ router.get("/allLoans/:key", async (req, res) => { }); // Route for API to get ALL items form the database -router.get("/allItems/:key", async (req, res) => { - if (!(await ensureValidApiKey(req, res))) return; - +router.get("/allItems/:key", apiKeyGuard, async (req, res) => { const result = await getItemsFromDatabaseV2(); if (result.success) { res.status(200).json(result.data);