From b5a1f9323a84f5e33e08de351662f022f54538fc Mon Sep 17 00:00:00 2001
From: Dominik Hebeler <dominik@suma-ev.de>
Date: Tue, 19 Mar 2024 10:22:33 +0100
Subject: [PATCH] move authorization

---
 pass/routes/api.js | 241 ++++++++++++++++++++++++---------------------
 1 file changed, 127 insertions(+), 114 deletions(-)

diff --git a/pass/routes/api.js b/pass/routes/api.js
index f225f5f..a61bfaf 100644
--- a/pass/routes/api.js
+++ b/pass/routes/api.js
@@ -10,134 +10,143 @@ const dayjs = require("dayjs");
 const NodeRSA = require("node-rsa");
 const PaymentReference = require("../app/PaymentReference");
 
-router.use("/key", authorizedOnly);
-
-router.post("/key/create", (req, res) => {
-  let amount = req.body.amount;
-  if (!amount) {
-    // If amount is not given but price is
-    // Calculate amount from price
-    let price = req.body.price;
-    if (price) {
-      amount = Math.ceil(price / config.get("price.per_token"));
-    } else {
-      res.status(403).json({
-        code: 403,
-        error: "Either :amount or :price must be supplied.",
-      });
-      return;
+router.post("/key/create",
+  authorizedOnly,
+  (req, res) => {
+    let amount = req.body.amount;
+    if (!amount) {
+      // If amount is not given but price is
+      // Calculate amount from price
+      let price = req.body.price;
+      if (price) {
+        amount = Math.ceil(price / config.get("price.per_token"));
+      } else {
+        res.status(403).json({
+          code: 403,
+          error: "Either :amount or :price must be supplied.",
+        });
+        return;
+      }
     }
-  }
 
-  return Key.GET_NEW_KEY()
-    .then((key) => {
-      return PaymentReference.CREATE_NEW_REQUEST(
-        amount,
-        key.get_key(),
-        dayjs().add("10", "years")
-      ).then((payment_reference) => {
-        return payment_reference.chargeKey().then(() => {
-          return res.status(201).json({
-            key: key.get_key(),
-            payment_reference: payment_reference.public_id,
-            charged: payment_reference.amount,
+    return Key.GET_NEW_KEY()
+      .then((key) => {
+        return PaymentReference.CREATE_NEW_REQUEST(
+          amount,
+          key.get_key(),
+          dayjs().add("10", "years")
+        ).then((payment_reference) => {
+          return payment_reference.chargeKey().then(() => {
+            return res.status(201).json({
+              key: key.get_key(),
+              payment_reference: payment_reference.public_id,
+              charged: payment_reference.amount,
+            });
           });
         });
+      })
+      .catch((reason) => {
+        res.status(423).json({
+          code: 423,
+          error: reason,
+          charged: 0,
+        });
       });
-    })
-    .catch((reason) => {
-      res.status(423).json({
-        code: 423,
-        error: reason,
-        charged: 0,
-      });
-    });
-});
+  });
 
 router.get("/key/:key", (req, res) => {
   Key.GET_KEY(req.params.key, false).then((key) => {
-    res.json({
+    let key_data = {
       key: key.get_key(),
       charge: key.get_charge(),
       expiration: key.get_expiration_date().format("YYYY-MM-DD HH:mm:ss"),
       charge_orders: key.get_charge_orders(),
-    });
+    };
+    if (!isAuthorized(req)) {
+      delete key_data.charge_orders;
+    }
+
+    res.json(key_data);
   });
 });
 
-router.post("/key/:key/discharge", (req, res) => {
-  let amount = req.body.amount;
-  if (!amount) {
-    // If amount is not given but price is
-    // Calculate amount from price
-    let price = req.body.price;
-    if (price) {
-      amount = Math.ceil(price / config.get("price.per_token"));
-    } else {
-      res.status(403).json({
-        code: 403,
-        error: "Either :amount or :price must be supplied.",
-      });
-      return;
+router.post("/key/:key/discharge",
+  authorizedOnly,
+  (req, res) => {
+    let amount = req.body.amount;
+    if (!amount) {
+      // If amount is not given but price is
+      // Calculate amount from price
+      let price = req.body.price;
+      if (price) {
+        amount = Math.ceil(price / config.get("price.per_token"));
+      } else {
+        res.status(403).json({
+          code: 403,
+          error: "Either :amount or :price must be supplied.",
+        });
+        return;
+      }
     }
-  }
-  let discharged_amount = 0;
-  let loaded_key = null;
-  Key.GET_KEY(req.params.key, true)
-    .then((key) => {
-      discharged_amount = key.discharge_key(amount);
-      loaded_key = key;
-      return key.save();
-    })
-    .then(() => {
-      res.status(201).json({
-        key: loaded_key.get_key(),
-        charge: loaded_key.get_charge(),
-        discharged: discharged_amount,
+    let discharged_amount = 0;
+    let loaded_key = null;
+    Key.GET_KEY(req.params.key, true)
+      .then((key) => {
+        discharged_amount = key.discharge_key(amount);
+        loaded_key = key;
+        return key.save();
+      })
+      .then(() => {
+        res.status(201).json({
+          key: loaded_key.get_key(),
+          charge: loaded_key.get_charge(),
+          discharged: discharged_amount,
+        });
       });
-    });
-});
+  });
 
-router.post("/key/:key/charge", (req, res) => {
-  let amount = req.body.amount;
-  if (!amount) {
-    // If amount is not given but price is
-    // Calculate amount from price
-    let price = req.body.price;
-    if (price) {
-      amount = Math.ceil(price / config.get("price.per_token"));
-    } else {
-      res.status(403).json({
-        code: 403,
-        error: "Either :amount or :price must be supplied.",
-      });
-      return;
+router.post("/key/:key/charge",
+  authorizedOnly,
+  (req, res) => {
+    let amount = req.body.amount;
+    if (!amount) {
+      // If amount is not given but price is
+      // Calculate amount from price
+      let price = req.body.price;
+      if (price) {
+        amount = Math.ceil(price / config.get("price.per_token"));
+      } else {
+        res.status(403).json({
+          code: 403,
+          error: "Either :amount or :price must be supplied.",
+        });
+        return;
+      }
     }
-  }
-  return Key.GET_KEY(req.params.key)
-    .then((key) => {
-      return PaymentReference.CREATE_NEW_REQUEST(
-        amount,
-        key.get_key(),
-        dayjs().add("10", "years")
-      ).then((payment_reference) => {
-        return payment_reference.chargeKey().then(() => {
-          return res.status(201).json({
-            key: key.get_key(),
-            payment_reference: payment_reference.public_id,
-            charged: payment_reference.amount,
+    return Key.GET_KEY(req.params.key)
+      .then((key) => {
+        return PaymentReference.CREATE_NEW_REQUEST(
+          amount,
+          key.get_key(),
+          dayjs().add("10", "years")
+        ).then((payment_reference) => {
+          return payment_reference.chargeKey().then(() => {
+            return res.status(201).json({
+              key: key.get_key(),
+              payment_reference: payment_reference.public_id,
+              charged: payment_reference.amount,
+            });
           });
         });
+      })
+      .catch((reason) => {
+        res.status(423).json({
+          code: 423,
+          error: reason,
+          charged: 0,
+        });
       });
-    })
-    .catch((reason) => {
-      res.status(423).json({
-        code: 423,
-        error: reason,
-        charged: 0,
-      });
-    });
-});
+  });
 
 router.get("/token/pubkey", async (req, res) => {
   let crypto = new Crypto();
@@ -312,6 +321,17 @@ router.use((req, res) => {
 });
 
 function authorizedOnly(req, res, next) {
+  if (!isAuthorized(req)) {
+    res.status(401).json({
+      code: 401,
+      error: "You are not authorized for API usage",
+    });
+  } else {
+    next();
+  }
+}
+
+function isAuthorized(req) {
   let auth_token = req.get("Authorization");
   let authorized = false;
   if (auth_token) {
@@ -321,14 +341,7 @@ function authorizedOnly(req, res, next) {
       authorized = true;
     }
   }
-  if (!authorized) {
-    res.status(401).json({
-      code: 401,
-      error: "You are not authorized for API usage",
-    });
-  } else {
-    next();
-  }
+  return authorized;
 }
 
 async function validateTokenStructure(value) {
-- 
GitLab