diff --git a/CHANGELOG.md b/CHANGELOG.md index bed8393..71598ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.0.1-alpha.16](https://github.com/DIG-Network/dig-incentive-server/compare/v0.0.1-alpha.15...v0.0.1-alpha.16) (2024-09-25) + + +### Bug Fixes + +* verify mnemonic ([66b97b0](https://github.com/DIG-Network/dig-incentive-server/commit/66b97b00850c067d68cea7e1e0de37e46b24dcc1)) + ### [0.0.1-alpha.15](https://github.com/DIG-Network/dig-incentive-server/compare/v0.0.1-alpha.14...v0.0.1-alpha.15) (2024-09-25) diff --git a/package-lock.json b/package-lock.json index 1dd9465..2968d28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dig-incentive-server", - "version": "0.0.1-alpha.15", + "version": "0.0.1-alpha.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dig-incentive-server", - "version": "0.0.1-alpha.15", + "version": "0.0.1-alpha.16", "license": "ISC", "dependencies": { "@dignetwork/dig-sdk": "^0.0.1-alpha.85", diff --git a/package.json b/package.json index e8c1c1a..a9300c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dig-incentive-server", - "version": "0.0.1-alpha.15", + "version": "0.0.1-alpha.16", "description": "", "type": "commonjs", "main": "./dist/index.js", diff --git a/src/middleware/verifyAuthorization.ts b/src/middleware/verifyAuthorization.ts new file mode 100644 index 0000000..5b9b5fe --- /dev/null +++ b/src/middleware/verifyAuthorization.ts @@ -0,0 +1,56 @@ +import { getCredentials } from "../utils/authUtils"; +import { Request, Response, NextFunction } from "express"; + +export const verifyAuthorization = async ( + req: Request, + res: Response, + next: NextFunction +) => { + try { + const credentials = await getCredentials(); + + if ( + !credentials || + credentials.password === "CHANGEME" || + credentials.username === "CHANGEME" + ) { + return res + .status(500) + .send( + "The propagation server does not have a valid username and password set. Please set the DIG_USERNAME and DIG_PASSWORD environment variables." + ); + } + + const authHeader = req.headers.authorization; + + if (!authHeader || !authHeader.startsWith("Basic ")) { + // No Authorization header or it's not Basic Auth + res.setHeader("WWW-Authenticate", 'Basic realm="Access to the site", charset="UTF-8"'); + return res.status(401).send("Unauthorized: Missing Basic Auth header"); + } + + // Decode base64 credentials + const base64Credentials = authHeader.split(" ")[1]; + const decodedCredentials = Buffer.from(base64Credentials, "base64").toString("utf-8"); + const [username, password] = decodedCredentials.split(":"); + + if (!username || !password) { + res.setHeader("WWW-Authenticate", 'Basic realm="Access to the site", charset="UTF-8"'); + return res.status(401).send("Unauthorized: Invalid Basic Auth format"); + } + + // Compare credentials + if (username !== credentials.username || password !== credentials.password) { + res.setHeader("WWW-Authenticate", 'Basic realm="Access to the site", charset="UTF-8"'); + return res.status(401).send("Unauthorized: Invalid username or password"); + } + + next(); // Credentials are valid; proceed to the next middleware + } catch (error) { + console.error("Error in verifyCredentials middleware:", error); + return res + .status(500) + .send("An error occurred while verifying the credentials."); + } +}; + diff --git a/src/middleware/verifyMnemonic.ts b/src/middleware/verifyMnemonic.ts index 21d59bd..7f47cd6 100644 --- a/src/middleware/verifyMnemonic.ts +++ b/src/middleware/verifyMnemonic.ts @@ -47,10 +47,36 @@ export const verifyCredentials = async ( ); } - next(); // Proceed to the next middleware or route handler + const authHeader = req.headers.authorization; + + if (!authHeader || !authHeader.startsWith("Basic ")) { + // No Authorization header or it's not Basic Auth + res.setHeader("WWW-Authenticate", 'Basic realm="Access to the site", charset="UTF-8"'); + return res.status(401).send("Unauthorized: Missing Basic Auth header"); + } + + // Decode base64 credentials + const base64Credentials = authHeader.split(" ")[1]; + const decodedCredentials = Buffer.from(base64Credentials, "base64").toString("utf-8"); + const [username, password] = decodedCredentials.split(":"); + + if (!username || !password) { + res.setHeader("WWW-Authenticate", 'Basic realm="Access to the site", charset="UTF-8"'); + return res.status(401).send("Unauthorized: Invalid Basic Auth format"); + } + + // Compare credentials + if (username !== credentials.username || password !== credentials.password) { + res.setHeader("WWW-Authenticate", 'Basic realm="Access to the site", charset="UTF-8"'); + return res.status(401).send("Unauthorized: Invalid username or password"); + } + + next(); // Credentials are valid; proceed to the next middleware } catch (error) { + console.error("Error in verifyCredentials middleware:", error); return res .status(500) - .send("An error occurred while verifying the mnemonic."); + .send("An error occurred while verifying the credentials."); } }; + diff --git a/src/routes/storeRoutes.ts b/src/routes/storeRoutes.ts index d6131fb..d1dff75 100644 --- a/src/routes/storeRoutes.ts +++ b/src/routes/storeRoutes.ts @@ -6,22 +6,23 @@ import { getIncentiveProgramById, deleteIncentiveProgram } from "../controllers/incentiveProgramController"; +import { verifyAuthorization } from "../middleware/verifyAuthorization"; const router = express.Router(); // Route to create a new incentive program -router.post("/incentive", express.json(), createIncentiveProgram); +router.post("/incentive", express.json(), verifyAuthorization, createIncentiveProgram); // Route to update an existing incentive program -router.put("/incentive", express.json(), updateIncentiveProgram); +router.put("/incentive", express.json(), verifyAuthorization, updateIncentiveProgram); // Route to get all incentive programs -router.get("/incentive", getAllIncentivePrograms); +router.get("/incentive", verifyAuthorization, getAllIncentivePrograms); // Route to get an incentive program by store ID -router.get("/incentive/:storeId", getIncentiveProgramById); +router.get("/incentive/:storeId", verifyAuthorization, getIncentiveProgramById); // Route to delete an incentive program by store ID -router.delete("/incentive", express.json(), deleteIncentiveProgram); +router.delete("/incentive", express.json(), verifyAuthorization, deleteIncentiveProgram); export { router as incentiveRoutes };