CVE-2023-4899: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') (CWE-89)
value:  SQL Injection in GitHub repository mintplex-labs/anything-llm prior to 0.0.1.
CWE description: The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component. Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data.
CVSS v3 base score: 8.8
Published: 2023-09-12T00:15Z
Repository: https://github.com/mintplex-labs/anything-llm
Language: JavaScript
Files changed: server/endpoints/admin.js, server/endpoints/api/admin/index.js, server/endpoints/api/workspace/index.js, server/endpoints/chat.js, server/endpoints/invite.js, server/endpoints/system.js, server/endpoints/workspaces.js, server/models/invite.js, server/models/user.js, server/models/workspace.js, server/package.json, server/utils/middleware/validApiKey.js, server/yarn.lock
Commit date: 2023-09-11 16:27:04 -0700
Commit message: patch SQL injection opportunities [LOW RISK] (#234)


Diff: diff --git a/server/endpoints/admin.js b/server/endpoints/admin.js
index e720110..0f3e0c5 100644
--- a/server/endpoints/admin.js
+++ b/server/endpoints/admin.js
@@ -1,5 +1,6 @@
+const { escape } = require("sqlstring-sqlite");
 const { ApiKey } = require("../models/apiKeys");
 const { Document } = require("../models/documents");
 const { Invite } = require("../models/invite");
 const { SystemSettings } = require("../models/systemSettings");
 const { User } = require("../models/user");
@@ -201,11 +202,11 @@ function adminEndpoints(app) {
         }
 
         const { workspaceId } = request.params;
         const { userIds } = reqBody(request);
         const { success, error } = await Workspace.updateUsers(
-          workspaceId,
+          escape(Number(workspaceId)),
           userIds
         );
         response.status(200).json({ success, error });
       } catch (e) {
         console.error(e);
@@ -225,20 +226,20 @@ function adminEndpoints(app) {
           return;
         }
 
         const { id } = request.params;
         const VectorDb = getVectorDbClass();
-        const workspace = Workspace.get(`id = ${id}`);
+        const workspace = Workspace.get(`id = ${escape(id)}`);
         if (!workspace) {
           response.sendStatus(404).end();
           return;
         }
 
-        await Workspace.delete(`id = ${id}`);
-        await DocumentVectors.deleteForWorkspace(id);
-        await Document.delete(`workspaceId = ${Number(id)}`);
-        await WorkspaceChats.delete(`workspaceId = ${Number(id)}`);
+        await Workspace.delete(`id = ${workspace.id}`);
+        await DocumentVectors.deleteForWorkspace(workspace.id);
+        await Document.delete(`workspaceId = ${Number(workspace.id)}`);
+        await WorkspaceChats.delete(`workspaceId = ${Number(workspace.id)}`);
         try {
           await VectorDb["delete-namespace"]({ namespace: workspace.slug });
         } catch (e) {
           console.error(e.message);
         }
@@ -260,11 +261,14 @@ function adminEndpoints(app) {
         if (!user || user?.role !== "admin") {
           response.sendStatus(401).end();
           return;
         }
         const { offset = 0 } = reqBody(request);
-        const chats = await WorkspaceChats.whereWithData(`id >= ${offset}`, 20);
+        const chats = await WorkspaceChats.whereWithData(
+          `id >= ${escape(offset)}`,
+          20
+        );
         const hasPages = (await WorkspaceChats.count()) > 20;
         response.status(200).json({ chats: chats.reverse(), hasPages });
       } catch (e) {
         console.error(e);
         response.sendStatus(500).end();
diff --git a/server/endpoints/api/admin/index.js b/server/endpoints/api/admin/index.js
index bc39e24..73d9efe 100644
--- a/server/endpoints/api/admin/index.js
+++ b/server/endpoints/api/admin/index.js
@@ -1,5 +1,6 @@
+const { escape } = require("sqlstring-sqlite");
 const { Invite } = require("../../../models/invite");
 const { SystemSettings } = require("../../../models/systemSettings");
 const { User } = require("../../../models/user");
 const { Workspace } = require("../../../models/workspace");
 const { WorkspaceChats } = require("../../../models/workspaceChats");
@@ -454,11 +455,11 @@ function apiAdminEndpoints(app) {
         }
 
         const { workspaceId } = request.params;
         const { userIds } = reqBody(request);
         const { success, error } = await Workspace.updateUsers(
-          workspaceId,
+          escape(Number(workspaceId)),
           userIds
         );
         response.status(200).json({ success, error });
       } catch (e) {
         console.error(e);
@@ -513,11 +514,14 @@ function apiAdminEndpoints(app) {
           response.sendStatus(401).end();
           return;
         }
 
         const { offset = 0 } = reqBody(request);
-        const chats = await WorkspaceChats.whereWithData(`id >= ${offset}`, 20);
+        const chats = await WorkspaceChats.whereWithData(
+          `id >= ${escape(offset)}`,
+          20
+        );
         const hasPages = (await WorkspaceChats.count()) > 20;
         response.status(200).json({ chats: chats.reverse(), hasPages });
       } catch (e) {
         console.error(e);
         response.sendStatus(500).end();
diff --git a/server/endpoints/api/workspace/index.js b/server/endpoints/api/workspace/index.js
index 35a16ed..f117c5f 100644
--- a/server/endpoints/api/workspace/index.js
+++ b/server/endpoints/api/workspace/index.js
@@ -1,5 +1,6 @@
+const { escape } = require("sqlstring-sqlite");
 const { Document } = require("../../../models/documents");
 const { Telemetry } = require("../../../models/telemetry");
 const { DocumentVectors } = require("../../../models/vectors");
 const { Workspace } = require("../../../models/workspace");
 const { WorkspaceChats } = require("../../../models/workspaceChats");
@@ -151,11 +152,11 @@ function apiWorkspaceEndpoints(app) {
       }
     }
     */
     try {
       const { slug } = request.params;
-      const workspace = await Workspace.get(`slug = '${slug}'`);
+      const workspace = await Workspace.get(`slug = ${escape(slug)}`);
       response.status(200).json({ workspace });
     } catch (e) {
       console.log(e.message, e);
       response.sendStatus(500).end();
     }
@@ -182,18 +183,18 @@ function apiWorkspaceEndpoints(app) {
     }
     */
       try {
         const { slug = "" } = request.params;
         const VectorDb = getVectorDbClass();
-        const workspace = await Workspace.get(`slug = '${slug}'`);
+        const workspace = await Workspace.get(`slug = ${escape(slug)}`);
 
         if (!workspace) {
           response.sendStatus(400).end();
           return;
         }
 
-        await Workspace.delete(`slug = '${slug.toLowerCase()}'`);
+        await Workspace.delete(`id = ${Number(workspace.id)}`);
         await DocumentVectors.deleteForWorkspace(workspace.id);
         await Document.delete(`workspaceId = ${Number(workspace.id)}`);
         await WorkspaceChats.delete(`workspaceId = ${Number(workspace.id)}`);
         try {
           await VectorDb["delete-namespace"]({ namespace: slug });
@@ -267,11 +268,11 @@ function apiWorkspaceEndpoints(app) {
     }
     */
       try {
         const { slug = null } = request.params;
         const data = reqBody(request);
-        const currWorkspace = await Workspace.get(`slug = '${slug}'`);
+        const currWorkspace = await Workspace.get(`slug = ${escape(slug)}`);
 
         if (!currWorkspace) {
           response.sendStatus(400).end();
           return;
         }
@@ -331,11 +332,11 @@ function apiWorkspaceEndpoints(app) {
       }
     }
     */
       try {
         const { slug } = request.params;
-        const workspace = await Workspace.get(`slug = '${slug}'`);
+        const workspace = await Workspace.get(`slug = ${escape(slug)}`);
 
         if (!workspace) {
           response.sendStatus(400).end();
           return;
         }
@@ -406,20 +407,22 @@ function apiWorkspaceEndpoints(app) {
     }
     */
       try {
         const { slug = null } = request.params;
         const { adds = [], deletes = [] } = reqBody(request);
-        const currWorkspace = await Workspace.get(`slug = '${slug}'`);
+        const currWorkspace = await Workspace.get(`slug = ${escape(slug)}`);
 
         if (!currWorkspace) {
           response.sendStatus(400).end();
           return;
         }
 
         await Document.removeDocuments(currWorkspace, deletes);
         await Document.addDocuments(currWorkspace, adds);
-        const updatedWorkspace = await Workspace.get(`slug = '${slug}'`);
+        const updatedWorkspace = await Workspace.get(
+          `id = ${Number(currWorkspace.id)}`
+        );
         response.status(200).json({ workspace: updatedWorkspace });
       } catch (e) {
         console.log(e.message, e);
         response.sendStatus(500).end();
       }
diff --git a/server/endpoints/chat.js b/server/endpoints/chat.js
index 5582dd9..365f0d3 100644
--- a/server/endpoints/chat.js
+++ b/server/endpoints/chat.js
@@ -4,10 +4,11 @@ const { Workspace } = require("../models/workspace");
 const { chatWithWorkspace } = require("../utils/chats");
 const { validatedRequest } = require("../utils/middleware/validatedRequest");
 const { WorkspaceChats } = require("../models/workspaceChats");
 const { SystemSettings } = require("../models/systemSettings");
 const { Telemetry } = require("../models/telemetry");
+const { escape } = require("sqlstring-sqlite");
 
 function chatEndpoints(app) {
   if (!app) return;
 
   app.post(
@@ -17,12 +18,12 @@ function chatEndpoints(app) {
       try {
         const user = await userFromSession(request, response);
         const { slug } = request.params;
         const { message, mode = "query" } = reqBody(request);
         const workspace = multiUserMode(response)
-          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
-          : await Workspace.get(`slug = '${slug}'`);
+          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
+          : await Workspace.get(`slug = ${escape(slug)}`);
 
         if (!workspace) {
           response.sendStatus(400).end();
           return;
         }
diff --git a/server/endpoints/invite.js b/server/endpoints/invite.js
index 3f3b145..24575f2 100644
--- a/server/endpoints/invite.js
+++ b/server/endpoints/invite.js
@@ -1,16 +1,17 @@
+const { escape } = require("sqlstring-sqlite");
 const { Invite } = require("../models/invite");
 const { User } = require("../models/user");
 const { reqBody } = require("../utils/http");
 
 function inviteEndpoints(app) {
   if (!app) return;
 
   app.get("/invite/:code", async (request, response) => {
     try {
       const { code } = request.params;
-      const invite = await Invite.get(`code = '${code}'`);
+      const invite = await Invite.get(`code = ${escape(code)}`);
       if (!invite) {
         response.status(200).json({ invite: null, error: "Invite not found." });
         return;
       }
 
@@ -32,11 +33,11 @@ function inviteEndpoints(app) {
 
   app.post("/invite/:code", async (request, response) => {
     try {
       const { code } = request.params;
       const userParams = reqBody(request);
-      const invite = await Invite.get(`code = '${code}'`);
+      const invite = await Invite.get(`code = ${escape(code)}`);
       if (!invite || invite.status !== "pending") {
         response
           .status(200)
           .json({ success: false, error: "Invite not found or is invalid." });
         return;
diff --git a/server/endpoints/system.js b/server/endpoints/system.js
index d493a2c..f7fa13c 100644
--- a/server/endpoints/system.js
+++ b/server/endpoints/system.js
@@ -36,10 +36,11 @@ const {
   DARK_LOGO_FILENAME,
 } = require("../utils/files/logo");
 const { Telemetry } = require("../models/telemetry");
 const { WelcomeMessages } = require("../models/welcomeMessages");
 const { ApiKey } = require("../models/apiKeys");
+const { escape } = require("sqlstring-sqlite");
 
 function systemEndpoints(app) {
   if (!app) return;
 
   app.get("/ping", (_, response) => {
@@ -94,11 +95,11 @@ function systemEndpoints(app) {
 
   app.post("/request-token", async (request, response) => {
     try {
       if (await SystemSettings.isMultiUserMode()) {
         const { username, password } = reqBody(request);
-        const existingUser = await User.get(`username = '${username}'`);
+        const existingUser = await User.get(`username = ${escape(username)}`);
 
         if (!existingUser) {
           response.status(200).json({
             user: null,
             valid: false,
diff --git a/server/endpoints/workspaces.js b/server/endpoints/workspaces.js
index 6d97406..923e3fd 100644
--- a/server/endpoints/workspaces.js
+++ b/server/endpoints/workspaces.js
@@ -11,10 +11,11 @@ const {
   processDocument,
 } = require("../utils/files/documentProcessor");
 const { validatedRequest } = require("../utils/middleware/validatedRequest");
 const { SystemSettings } = require("../models/systemSettings");
 const { Telemetry } = require("../models/telemetry");
+const { escape } = require("sqlstring-sqlite");
 const { handleUploads } = setupMulter();
 
 function workspaceEndpoints(app) {
   if (!app) return;
 
@@ -42,12 +43,12 @@ function workspaceEndpoints(app) {
       try {
         const user = await userFromSession(request, response);
         const { slug = null } = request.params;
         const data = reqBody(request);
         const currWorkspace = multiUserMode(response)
-          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
-          : await Workspace.get(`slug = '${slug}'`);
+          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
+          : await Workspace.get(`slug = ${escape(slug)}`);
 
         if (!currWorkspace) {
           response.sendStatus(400).end();
           return;
         }
@@ -103,21 +104,23 @@ function workspaceEndpoints(app) {
       try {
         const user = await userFromSession(request, response);
         const { slug = null } = request.params;
         const { adds = [], deletes = [] } = reqBody(request);
         const currWorkspace = multiUserMode(response)
-          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
-          : await Workspace.get(`slug = '${slug}'`);
+          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
+          : await Workspace.get(`slug = ${escape(slug)}`);
 
         if (!currWorkspace) {
           response.sendStatus(400).end();
           return;
         }
 
         await Document.removeDocuments(currWorkspace, deletes);
         await Document.addDocuments(currWorkspace, adds);
-        const updatedWorkspace = await Workspace.get(`slug = '${slug}'`);
+        const updatedWorkspace = await Workspace.get(
+          `id = ${currWorkspace.id}`
+        );
         response.status(200).json({ workspace: updatedWorkspace });
       } catch (e) {
         console.log(e.message, e);
         response.sendStatus(500).end();
       }
@@ -131,12 +134,12 @@ function workspaceEndpoints(app) {
       try {
         const { slug = "" } = request.params;
         const user = await userFromSession(request, response);
         const VectorDb = getVectorDbClass();
         const workspace = multiUserMode(response)
-          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
-          : await Workspace.get(`slug = '${slug}'`);
+          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
+          : await Workspace.get(`slug = ${escape(slug)}`);
 
         if (!workspace) {
           response.sendStatus(400).end();
           return;
         }
@@ -149,11 +152,11 @@ function workspaceEndpoints(app) {
             response.sendStatus(500).end();
             return;
           }
         }
 
-        await Workspace.delete(`slug = '${slug.toLowerCase()}'`);
+        await Workspace.delete(`id = ${Number(workspace.id)}`);
         await DocumentVectors.deleteForWorkspace(workspace.id);
         await Document.delete(`workspaceId = ${Number(workspace.id)}`);
         await WorkspaceChats.delete(`workspaceId = ${Number(workspace.id)}`);
         try {
           await VectorDb["delete-namespace"]({ namespace: slug });
@@ -185,12 +188,12 @@ function workspaceEndpoints(app) {
   app.get("/workspace/:slug", [validatedRequest], async (request, response) => {
     try {
       const { slug } = request.params;
       const user = await userFromSession(request, response);
       const workspace = multiUserMode(response)
-        ? await Workspace.getWithUser(user, `slug = '${slug}'`)
-        : await Workspace.get(`slug = '${slug}'`);
+        ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
+        : await Workspace.get(`slug = ${escape(slug)}`);
 
       response.status(200).json({ workspace });
     } catch (e) {
       console.log(e.message, e);
       response.sendStatus(500).end();
@@ -203,12 +206,12 @@ function workspaceEndpoints(app) {
     async (request, response) => {
       try {
         const { slug } = request.params;
         const user = await userFromSession(request, response);
         const workspace = multiUserMode(response)
-          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
-          : await Workspace.get(`slug = '${slug}'`);
+          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
+          : await Workspace.get(`slug = ${escape(slug)}`);
 
         if (!workspace) {
           response.sendStatus(400).end();
           return;
         }
diff --git a/server/models/invite.js b/server/models/invite.js
index e32c9dc..a65e7cd 100644
--- a/server/models/invite.js
+++ b/server/models/invite.js
@@ -1,5 +1,7 @@
+const { escape } = require("sqlstring-sqlite");
+
 const Invite = {
   tablename: "invites",
   writable: [],
   colsInit: `
   id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -67,11 +69,11 @@ const Invite = {
     db.close();
 
     return { invite, error: null };
   },
   deactivate: async function (inviteId = null) {
-    const invite = await this.get(`id = ${inviteId}`);
+    const invite = await this.get(`id = ${escape(inviteId)}`);
     if (!invite) return { success: false, error: "Invite does not exist." };
     if (invite.status !== "pending")
       return { success: false, error: "Invite is not in pending status." };
 
     const db = await this.db();
@@ -94,11 +96,11 @@ const Invite = {
     }
 
     return { success: true, error: null };
   },
   markClaimed: async function (inviteId = null, user) {
-    const invite = await this.get(`id = ${inviteId}`);
+    const invite = await this.get(`id = ${escape(inviteId)}`);
     if (!invite) return { success: false, error: "Invite does not exist." };
     if (invite.status !== "pending")
       return { success: false, error: "Invite is not in pending status." };
 
     const db = await this.db();
diff --git a/server/models/user.js b/server/models/user.js
index 9bfee35..5020377 100644
--- a/server/models/user.js
+++ b/server/models/user.js
@@ -1,5 +1,7 @@
+const { escape } = require("sqlstring-sqlite");
+
 const User = {
   tablename: "users",
   writable: [],
   colsInit: `
   id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -64,17 +66,17 @@ const User = {
     db.close();
 
     return { user, error: null };
   },
   update: async function (userId, updates = {}) {
-    const user = await this.get(`id = ${userId}`);
+    const user = await this.get(`id = ${escape(userId)}`);
     if (!user) return { success: false, error: "User does not exist." };
     const { username, password, role, suspended = 0 } = updates;
     const toUpdate = { suspended };
 
     if (user.username !== username && username?.length > 0) {
-      const usedUsername = !!(await this.get(`username = '${username}'`));
+      const usedUsername = !!(await this.get(`username = ${escape(username)}`));
       if (usedUsername)
         return { success: false, error: `${username} is already in use.` };
       toUpdate.username = username;
     }
 
diff --git a/server/models/workspace.js b/server/models/workspace.js
index 5049a2b..ac0361d 100644
--- a/server/models/workspace.js
+++ b/server/models/workspace.js
@@ -1,9 +1,10 @@
 const slugify = require("slugify");
 const { Document } = require("./documents");
 const { checkForMigrations } = require("../utils/database");
 const { WorkspaceUser } = require("./workspaceUsers");
+const { escape } = require("sqlstring-sqlite");
 
 const Workspace = {
   tablename: "workspaces",
   writable: [
     // Used for generic updates so we can validate keys in request body
@@ -79,11 +80,11 @@ const Workspace = {
   },
   new: async function (name = null, creatorId = null) {
     if (!name) return { result: null, message: "name cannot be null" };
     var slug = slugify(name, { lower: true });
 
-    const existingBySlug = await this.get(`slug = '${slug}'`);
+    const existingBySlug = await this.get(`slug = ${escape(slug)}`);
     if (existingBySlug !== null) {
       const slugSeed = Math.floor(10000000 + Math.random() * 90000000);
       slug = slugify(`${name}-${slugSeed}`, { lower: true });
     }
 
diff --git a/server/package.json b/server/package.json
index c176338..187304e 100644
--- a/server/package.json
+++ b/server/package.json
@@ -40,10 +40,11 @@
     "posthog-node": "^3.1.1",
     "serve-index": "^1.9.1",
     "slugify": "^1.6.6",
     "sqlite": "^4.2.1",
     "sqlite3": "^5.1.6",
+    "sqlstring-sqlite": "^0.1.1",
     "swagger-autogen": "^2.23.5",
     "swagger-ui-express": "^5.0.0",
     "uuid": "^9.0.0",
     "uuid-apikey": "^1.5.3",
     "vectordb": "0.1.12",
@@ -51,6 +52,6 @@
   },
   "devDependencies": {
     "nodemon": "^2.0.22",
     "prettier": "^2.4.1"
   }
-}
\ No newline at end of file
+}
diff --git a/server/utils/middleware/validApiKey.js b/server/utils/middleware/validApiKey.js
index 6c74310..3e819ab 100644
--- a/server/utils/middleware/validApiKey.js
+++ b/server/utils/middleware/validApiKey.js
@@ -1,5 +1,6 @@
+const { escape } = require("sqlstring-sqlite");
 const { ApiKey } = require("../../models/apiKeys");
 const { SystemSettings } = require("../../models/systemSettings");
 
 async function validApiKey(request, response, next) {
   const multiUserMode = await SystemSettings.isMultiUserMode();
@@ -12,12 +13,11 @@ async function validApiKey(request, response, next) {
       error: "No valid api key found.",
     });
     return;
   }
 
-  const apiKey = await ApiKey.get(`secret = '${bearerKey}'`);
-  if (!apiKey) {
+  if (!(await ApiKey.get(`secret = ${escape(bearerKey)}`))) {
     response.status(403).json({
       error: "No valid api key found.",
     });
     return;
   }
diff --git a/server/yarn.lock b/server/yarn.lock
index 1d47eb6..3350ab3 100644
--- a/server/yarn.lock
+++ b/server/yarn.lock
@@ -2383,10 +2383,15 @@ sqlite3@^5.1.6:
 sqlite@^4.2.1:
   version "4.2.1"
   resolved "https://registry.yarnpkg.com/sqlite/-/sqlite-4.2.1.tgz#d4eedfd1ad702f79110792375f4241a90c75c828"
   integrity sha512-Tll0Ndvnwkuv5Hn6WIbh26rZiYQORuH1t5m/or9LUpSmDmmyFG89G9fKrSeugMPxwmEIXoVxqTun4LbizTs4uw==
 
+sqlstring-sqlite@^0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/sqlstring-sqlite/-/sqlstring-sqlite-0.1.1.tgz#c8c61810663f2e59a6b0d737b70a8752bda3a078"
+  integrity sha512-9CAYUJ0lEUPYJrswqiqdINNSfq3jqWo/bFJ7tufdoNeSK0Fy+d1kFTxjqO9PIqza0Kri+ZtYMfPVf1aZaFOvrQ==
+
 ssri@^8.0.0, ssri@^8.0.1:
   version "8.0.1"
   resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af"
   integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==
   dependencies:

Vulnerable code:           workspaceId,
        const workspace = Workspace.get(`id = ${id}`);
        await Workspace.delete(`id = ${id}`);
        await DocumentVectors.deleteForWorkspace(id);
        await Document.delete(`workspaceId = ${Number(id)}`);
        await WorkspaceChats.delete(`workspaceId = ${Number(id)}`);
        const chats = await WorkspaceChats.whereWithData(`id >= ${offset}`, 20);
          workspaceId,
        const chats = await WorkspaceChats.whereWithData(`id >= ${offset}`, 20);
      const workspace = await Workspace.get(`slug = '${slug}'`);
        const workspace = await Workspace.get(`slug = '${slug}'`);
        await Workspace.delete(`slug = '${slug.toLowerCase()}'`);
        const currWorkspace = await Workspace.get(`slug = '${slug}'`);
        const workspace = await Workspace.get(`slug = '${slug}'`);
        const currWorkspace = await Workspace.get(`slug = '${slug}'`);
        const updatedWorkspace = await Workspace.get(`slug = '${slug}'`);
          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
          : await Workspace.get(`slug = '${slug}'`);
      const invite = await Invite.get(`code = '${code}'`);
      const invite = await Invite.get(`code = '${code}'`);
        const existingUser = await User.get(`username = '${username}'`);
          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
          : await Workspace.get(`slug = '${slug}'`);
          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
          : await Workspace.get(`slug = '${slug}'`);
        const updatedWorkspace = await Workspace.get(`slug = '${slug}'`);
          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
          : await Workspace.get(`slug = '${slug}'`);
        await Workspace.delete(`slug = '${slug.toLowerCase()}'`);
        ? await Workspace.getWithUser(user, `slug = '${slug}'`)
        : await Workspace.get(`slug = '${slug}'`);
          ? await Workspace.getWithUser(user, `slug = '${slug}'`)
          : await Workspace.get(`slug = '${slug}'`);
    const invite = await this.get(`id = ${inviteId}`);
    const invite = await this.get(`id = ${inviteId}`);
    const user = await this.get(`id = ${userId}`);
      const usedUsername = !!(await this.get(`username = '${username}'`));
    const existingBySlug = await this.get(`slug = '${slug}'`);
}
  const apiKey = await ApiKey.get(`secret = '${bearerKey}'`);
  if (!apiKey) {
Fixed code: const { escape } = require("sqlstring-sqlite");
          escape(Number(workspaceId)),
        const workspace = Workspace.get(`id = ${escape(id)}`);
        await Workspace.delete(`id = ${workspace.id}`);
        await DocumentVectors.deleteForWorkspace(workspace.id);
        await Document.delete(`workspaceId = ${Number(workspace.id)}`);
        await WorkspaceChats.delete(`workspaceId = ${Number(workspace.id)}`);
        const chats = await WorkspaceChats.whereWithData(
          `id >= ${escape(offset)}`,
          20
        );
const { escape } = require("sqlstring-sqlite");
          escape(Number(workspaceId)),
        const chats = await WorkspaceChats.whereWithData(
          `id >= ${escape(offset)}`,
          20
        );
const { escape } = require("sqlstring-sqlite");
      const workspace = await Workspace.get(`slug = ${escape(slug)}`);
        const workspace = await Workspace.get(`slug = ${escape(slug)}`);
        await Workspace.delete(`id = ${Number(workspace.id)}`);
        const currWorkspace = await Workspace.get(`slug = ${escape(slug)}`);
        const workspace = await Workspace.get(`slug = ${escape(slug)}`);
        const currWorkspace = await Workspace.get(`slug = ${escape(slug)}`);
        const updatedWorkspace = await Workspace.get(
          `id = ${Number(currWorkspace.id)}`
        );
const { escape } = require("sqlstring-sqlite");
          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
          : await Workspace.get(`slug = ${escape(slug)}`);
const { escape } = require("sqlstring-sqlite");
      const invite = await Invite.get(`code = ${escape(code)}`);
      const invite = await Invite.get(`code = ${escape(code)}`);
const { escape } = require("sqlstring-sqlite");
        const existingUser = await User.get(`username = ${escape(username)}`);
const { escape } = require("sqlstring-sqlite");
          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
          : await Workspace.get(`slug = ${escape(slug)}`);
          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
          : await Workspace.get(`slug = ${escape(slug)}`);
        const updatedWorkspace = await Workspace.get(
          `id = ${currWorkspace.id}`
        );
          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
          : await Workspace.get(`slug = ${escape(slug)}`);
        await Workspace.delete(`id = ${Number(workspace.id)}`);
        ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
        : await Workspace.get(`slug = ${escape(slug)}`);
          ? await Workspace.getWithUser(user, `slug = ${escape(slug)}`)
          : await Workspace.get(`slug = ${escape(slug)}`);
const { escape } = require("sqlstring-sqlite");

    const invite = await this.get(`id = ${escape(inviteId)}`);
    const invite = await this.get(`id = ${escape(inviteId)}`);
const { escape } = require("sqlstring-sqlite");

    const user = await this.get(`id = ${escape(userId)}`);
      const usedUsername = !!(await this.get(`username = ${escape(username)}`));
const { escape } = require("sqlstring-sqlite");
    const existingBySlug = await this.get(`slug = ${escape(slug)}`);
    "sqlstring-sqlite": "^0.1.1",
}
const { escape } = require("sqlstring-sqlite");
  if (!(await ApiKey.get(`secret = ${escape(bearerKey)}`))) {
sqlstring-sqlite@^0.1.1:
  version "0.1.1"
  resolved "https://registry.yarnpkg.com/sqlstring-sqlite/-/sqlstring-sqlite-0.1.1.tgz#c8c61810663f2e59a6b0d737b70a8752bda3a078"
  integrity sha512-9CAYUJ0lEUPYJrswqiqdINNSfq3jqWo/bFJ7tufdoNeSK0Fy+d1kFTxjqO9PIqza0Kri+ZtYMfPVf1aZaFOvrQ==