Refactor API key validation: streamline error handling and enforce API key presence in routes
This commit is contained in:
@@ -341,17 +341,6 @@ router.get("/apiKeys", authenticate, async (req, res) => {
|
|||||||
return res.status(500).json({ message: "Failed to fetch API keys" });
|
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) => {
|
router.delete("/deleteAPKey/:id", authenticate, async (req, res) => {
|
||||||
const apiKeyId = req.params.id;
|
const apiKeyId = req.params.id;
|
||||||
const result = await deleteAPKey(apiKeyId);
|
const result = await deleteAPKey(apiKeyId);
|
||||||
|
@@ -15,32 +15,40 @@ const router = express.Router();
|
|||||||
|
|
||||||
async function validateAPIKey(apiKey) {
|
async function validateAPIKey(apiKey) {
|
||||||
try {
|
try {
|
||||||
|
if (!apiKey) return false;
|
||||||
const result = await getAPIkey();
|
const result = await getAPIkey();
|
||||||
if (!result.success || !Array.isArray(result.data)) return false;
|
if (!result?.success || !Array.isArray(result.data)) return false;
|
||||||
|
return result.data.some((row) => String(row.apiKey) === String(apiKey));
|
||||||
return result.data.some((row) => {
|
|
||||||
const val = String(row?.apiKey ?? row?.key ?? row?.api_key);
|
|
||||||
return val === String(apiKey);
|
|
||||||
});
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("validateAPIKey error:", err);
|
console.error("validateAPIKey error:", err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ensureValidApiKey(req, res) {
|
// Add a guard that returns Access Denied instead of hanging
|
||||||
const isValid = await validateAPIKey(req.params.key);
|
const apiKeyGuard = async (req, res, next) => {
|
||||||
if (!isValid) {
|
try {
|
||||||
res.status(403).json({ message: "Access denied" });
|
const key = req.params.key;
|
||||||
return false;
|
if (!key) {
|
||||||
|
return res
|
||||||
|
.status(401)
|
||||||
|
.json({ message: "Access denied: missing API key" });
|
||||||
}
|
}
|
||||||
return true;
|
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" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Route for API to get ALL items from the database
|
// Route for API to get ALL items from the database
|
||||||
router.get("/items/:key", async (req, res) => {
|
router.get("/items/:key", apiKeyGuard, async (req, res) => {
|
||||||
if (!(await ensureValidApiKey(req, res))) return;
|
|
||||||
|
|
||||||
const result = await getItemsFromDatabaseV2();
|
const result = await getItemsFromDatabaseV2();
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
res.status(200).json({ data: result.data });
|
res.status(200).json({ data: result.data });
|
||||||
@@ -50,9 +58,10 @@ router.get("/items/:key", async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Route for API to control the position of an item
|
// Route for API to control the position of an item
|
||||||
router.post("/controlInSafe/:key/:itemId/:state", async (req, res) => {
|
router.post(
|
||||||
if (!(await ensureValidApiKey(req, res))) return;
|
"/controlInSafe/:key/:itemId/:state",
|
||||||
|
apiKeyGuard,
|
||||||
|
async (req, res) => {
|
||||||
const itemId = req.params.itemId;
|
const itemId = req.params.itemId;
|
||||||
const state = req.params.state;
|
const state = req.params.state;
|
||||||
|
|
||||||
@@ -66,12 +75,11 @@ router.post("/controlInSafe/:key/:itemId/:state", async (req, res) => {
|
|||||||
} else {
|
} else {
|
||||||
res.status(400).json({ message: "Invalid state value" });
|
res.status(400).json({ message: "Invalid state value" });
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// Route for API to get a loan by its code
|
// Route for API to get a loan by its code
|
||||||
router.get("/getLoanByCode/:key/:loan_code", async (req, res) => {
|
router.get("/getLoanByCode/:key/:loan_code", apiKeyGuard, async (req, res) => {
|
||||||
if (!(await ensureValidApiKey(req, res))) return;
|
|
||||||
|
|
||||||
const loan_code = req.params.loan_code;
|
const loan_code = req.params.loan_code;
|
||||||
const result = await getLoanByCodeV2(loan_code);
|
const result = await getLoanByCodeV2(loan_code);
|
||||||
if (result.success) {
|
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
|
// Route for API to set the return date by the loan code
|
||||||
router.post("/setReturnDate/:key/:loan_code", async (req, res) => {
|
router.post("/setReturnDate/:key/:loan_code", apiKeyGuard, async (req, res) => {
|
||||||
if (!(await ensureValidApiKey(req, res))) return;
|
|
||||||
|
|
||||||
const loanCode = req.params.loan_code;
|
const loanCode = req.params.loan_code;
|
||||||
const result = await setReturnDateV2(loanCode);
|
const result = await setReturnDateV2(loanCode);
|
||||||
if (result.success) {
|
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
|
// Route for API to set the take away date by the loan code
|
||||||
router.post("/setTakeDate/:key/:loan_code", async (req, res) => {
|
router.post("/setTakeDate/:key/:loan_code", apiKeyGuard, async (req, res) => {
|
||||||
if (!(await ensureValidApiKey(req, res))) return;
|
|
||||||
|
|
||||||
const loanCode = req.params.loan_code;
|
const loanCode = req.params.loan_code;
|
||||||
const result = await setTakeDateV2(loanCode);
|
const result = await setTakeDateV2(loanCode);
|
||||||
if (result.success) {
|
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
|
// Route for API to get ALL loans from the database without sensitive info
|
||||||
router.get("/allLoans/:key", async (req, res) => {
|
router.get("/allLoans/:key", apiKeyGuard, async (req, res) => {
|
||||||
if (!(await ensureValidApiKey(req, res))) return;
|
|
||||||
|
|
||||||
const result = await getAllLoansV2();
|
const result = await getAllLoansV2();
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
return res.status(200).json(result.data);
|
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
|
// Route for API to get ALL items form the database
|
||||||
router.get("/allItems/:key", async (req, res) => {
|
router.get("/allItems/:key", apiKeyGuard, async (req, res) => {
|
||||||
if (!(await ensureValidApiKey(req, res))) return;
|
|
||||||
|
|
||||||
const result = await getItemsFromDatabaseV2();
|
const result = await getItemsFromDatabaseV2();
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
res.status(200).json(result.data);
|
res.status(200).json(result.data);
|
||||||
|
Reference in New Issue
Block a user