From a83d105764194e78d0985de7880d54f06ed1e627 Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Tue, 11 Apr 2023 11:05:30 -0700
Subject: [PATCH] Cleanup data validation

---
 src/utils/proxy/handlers/credentialed.js | 18 +++++++++---------
 src/utils/proxy/handlers/generic.js      | 18 +++++++++---------
 src/utils/proxy/validate-widget-data.js  | 22 ++++++++++++++++------
 3 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/src/utils/proxy/handlers/credentialed.js b/src/utils/proxy/handlers/credentialed.js
index 56bbb151..93cdb995 100644
--- a/src/utils/proxy/handlers/credentialed.js
+++ b/src/utils/proxy/handlers/credentialed.js
@@ -67,6 +67,10 @@ export default async function credentialedProxyHandler(req, res, map) {
 
       let resultData = data;
 
+      if (resultData.error?.url) {
+        resultData.error.url = sanitizeErrorURL(url);
+      }
+
       if (status === 204 || status === 304) {
         return res.status(status).end();
       }
@@ -74,16 +78,12 @@ export default async function credentialedProxyHandler(req, res, map) {
       if (status >= 400) {
         logger.error("HTTP Error %d calling %s", status, url.toString());
       }
-
-      if (!validateWidgetData(widget, endpoint, data)) {
-        if (data.error && data.error.url) {
-          data.error.url = sanitizeErrorURL(url);
+      
+      if (status === 200) {
+        if (!validateWidgetData(widget, endpoint, resultData)) {
+          return res.status(500).json({error: {message: "Invalid data", url: sanitizeErrorURL(url), data: resultData}});
         }
-        return res.status(500).json({error: {message: "Invalid data", url: sanitizeErrorURL(url), data}});
-      }
-
-      if (status === 200 && map) {
-        resultData = map(data);
+        if (map) resultData = map(resultData);
       }
 
       if (contentType) res.setHeader("Content-Type", contentType);
diff --git a/src/utils/proxy/handlers/generic.js b/src/utils/proxy/handlers/generic.js
index 08dd8cb3..b8db9618 100644
--- a/src/utils/proxy/handlers/generic.js
+++ b/src/utils/proxy/handlers/generic.js
@@ -39,15 +39,15 @@ export default async function genericProxyHandler(req, res, map) {
 
       let resultData = data;
       
-      if (!validateWidgetData(widget, endpoint, resultData)) {
-        if (resultData.error && resultData.error.url) {
-          resultData.error.url = sanitizeErrorURL(url);
-        }
-        return res.status(status).json({error: {message: "Invalid data", url: sanitizeErrorURL(url), data: resultData}});
+      if (resultData.error?.url) {
+        resultData.error.url = sanitizeErrorURL(url);
       }
-
-      if (status === 200 && map) {
-        resultData = map(data);
+      
+      if (status === 200) {
+        if (!validateWidgetData(widget, endpoint, resultData)) {
+          return res.status(status).json({error: {message: "Invalid data", url: sanitizeErrorURL(url), data: resultData}});
+        }
+        if (map) resultData = map(resultData);
       }
 
       if (contentType) res.setHeader("Content-Type", contentType);
@@ -58,7 +58,7 @@ export default async function genericProxyHandler(req, res, map) {
 
       if (status >= 400) {
         logger.debug("HTTP Error %d calling %s//%s%s...", status, url.protocol, url.hostname, url.pathname);
-        return res.status(status).json({error: {message: "HTTP Error", url: sanitizeErrorURL(url), data}});
+        return res.status(status).json({error: {message: "HTTP Error", url: sanitizeErrorURL(url), resultData}});
       }
 
       return res.status(status).send(resultData);
diff --git a/src/utils/proxy/validate-widget-data.js b/src/utils/proxy/validate-widget-data.js
index e81606ef..cfddc073 100644
--- a/src/utils/proxy/validate-widget-data.js
+++ b/src/utils/proxy/validate-widget-data.js
@@ -1,23 +1,33 @@
+/* eslint-disable no-console */
 import widgets from "widgets/widgets";
 
 export default function validateWidgetData(widget, endpoint, data) {
     let valid = true;
     let dataParsed = data;
+    let error;
     if (Buffer.isBuffer(data)) {
         try {
             dataParsed = JSON.parse(data);
         } catch (e) {
+            error = e;
             valid = false;
         }
     }
 
     if (dataParsed && Object.entries(dataParsed).length) {
-        const validate = widgets[widget.type]?.mappings?.[endpoint]?.validate;
-        validate?.forEach(key => {
-            if (dataParsed[key] === undefined) {
-                valid = false;
-            }
-        });
+        const mappings = widgets[widget.type]?.mappings;
+        if (mappings) {
+            const mapping = Object.values(mappings).find(m => m.endpoint === endpoint);
+            mapping?.validate?.forEach(key => {
+                if (dataParsed[key] === undefined) {
+                    valid = false;
+                }
+            });
+        }
+    }
+
+    if (!valid) {
+        console.warn(`Invalid data for widget '${widget.type}' endpoint '${endpoint}':\nParse error: ${error ?? "none"}\nData: ${JSON.stringify(data, null, " ")}`);
     }
     
     return valid;