From c2d37ccce5f889e9a2a2ae7f30e846d5f1493a67 Mon Sep 17 00:00:00 2001
From: Timothy Carambat <rambat1010@gmail.com>
Date: Wed, 22 May 2024 12:32:39 -0500
Subject: [PATCH] Limit return object of `user` when returned in some endpoints
 (#1492)

---
 server/endpoints/admin.js           |  5 +----
 server/endpoints/api/admin/index.js |  5 +----
 server/endpoints/system.js          |  6 +++---
 server/models/user.js               | 21 +++++++++++++++++++--
 4 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/server/endpoints/admin.js b/server/endpoints/admin.js
index 959e023ff..9b836b19a 100644
--- a/server/endpoints/admin.js
+++ b/server/endpoints/admin.js
@@ -33,10 +33,7 @@ function adminEndpoints(app) {
     [validatedRequest, strictMultiUserRoleValid([ROLES.admin, ROLES.manager])],
     async (_request, response) => {
       try {
-        const users = (await User.where()).map((user) => {
-          const { password, ...rest } = user;
-          return rest;
-        });
+        const users = await User.where();
         response.status(200).json({ users });
       } catch (e) {
         console.error(e);
diff --git a/server/endpoints/api/admin/index.js b/server/endpoints/api/admin/index.js
index 228777ab5..95b8e7916 100644
--- a/server/endpoints/api/admin/index.js
+++ b/server/endpoints/api/admin/index.js
@@ -73,10 +73,7 @@ function apiAdminEndpoints(app) {
         return;
       }
 
-      const users = (await User.where()).map((user) => {
-        const { password, ...rest } = user;
-        return rest;
-      });
+      const users = await User.where();
       response.status(200).json({ users });
     } catch (e) {
       console.error(e);
diff --git a/server/endpoints/system.js b/server/endpoints/system.js
index 86aacac48..f4057a404 100644
--- a/server/endpoints/system.js
+++ b/server/endpoints/system.js
@@ -110,7 +110,7 @@ function systemEndpoints(app) {
 
       if (await SystemSettings.isMultiUserMode()) {
         const { username, password } = reqBody(request);
-        const existingUser = await User.get({ username: String(username) });
+        const existingUser = await User._get({ username: String(username) });
 
         if (!existingUser) {
           await EventLogs.logEvent(
@@ -188,7 +188,7 @@ function systemEndpoints(app) {
           // Return recovery codes to frontend
           response.status(200).json({
             valid: true,
-            user: existingUser,
+            user: User.filterFields(existingUser),
             token: makeJWT(
               { id: existingUser.id, username: existingUser.username },
               "30d"
@@ -201,7 +201,7 @@ function systemEndpoints(app) {
 
         response.status(200).json({
           valid: true,
-          user: existingUser,
+          user: User.filterFields(existingUser),
           token: makeJWT(
             { id: existingUser.id, username: existingUser.username },
             "30d"
diff --git a/server/models/user.js b/server/models/user.js
index ecb620ee4..a1aeb2c63 100644
--- a/server/models/user.js
+++ b/server/models/user.js
@@ -19,6 +19,12 @@ const User = {
         return String(value);
     }
   },
+
+  filterFields: function (user = {}) {
+    const { password, ...rest } = user;
+    return { ...rest };
+  },
+
   create: async function ({ username, password, role = "default" }) {
     const passwordCheck = this.checkPasswordComplexity(password);
     if (!passwordCheck.checkedOK) {
@@ -35,7 +41,7 @@ const User = {
           role,
         },
       });
-      return { user, error: null };
+      return { user: this.filterFields(user), error: null };
     } catch (error) {
       console.error("FAILED TO CREATE USER.", error.message);
       return { user: null, error: error.message };
@@ -127,6 +133,17 @@ const User = {
   },
 
   get: async function (clause = {}) {
+    try {
+      const user = await prisma.users.findFirst({ where: clause });
+      return user ? this.filterFields({ ...user }) : null;
+    } catch (error) {
+      console.error(error.message);
+      return null;
+    }
+  },
+
+  // Returns user object with all fields
+  _get: async function (clause = {}) {
     try {
       const user = await prisma.users.findFirst({ where: clause });
       return user ? { ...user } : null;
@@ -162,7 +179,7 @@ const User = {
         where: clause,
         ...(limit !== null ? { take: limit } : {}),
       });
-      return users;
+      return users.map((usr) => this.filterFields(usr));
     } catch (error) {
       console.error(error.message);
       return [];
-- 
GitLab