diff --git a/backend/endpoints/system.js b/backend/endpoints/system.js index a4113c5..a73a53d 100644 --- a/backend/endpoints/system.js +++ b/backend/endpoints/system.js @@ -4,6 +4,7 @@ process.env.NODE_ENV === "development" const { SystemSettings } = require("../models/systemSettings"); const { systemInit } = require("../utils/boot"); const { reqBody, userFromSession } = require("../utils/http"); +const { validatedRequest } = require("../utils/middleware/validatedRequest"); // const { validateTablePragmas } = require("../utils/database"); function systemEndpoints(app) { @@ -18,60 +19,72 @@ function systemEndpoints(app) { response.sendStatus(200).end(); }); - app.get("/system/setting/:label/exists", async (request, response) => { - try { - const { label } = request.params; - if (!SystemSettings.supportedFields.includes(label)) { - response.status(404).json({ label, exists: false }); - return; - } + app.get( + "/system/setting/:label/exists", + [validatedRequest], + async (request, response) => { + try { + const { label } = request.params; + if (!SystemSettings.supportedFields.includes(label)) { + response.status(404).json({ label, exists: false }); + return; + } - const config = await SystemSettings.get(`label = '${label}'`); - response.status(200).json({ label, exists: !!config?.value }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); + const config = await SystemSettings.get(`label = '${label}'`); + response.status(200).json({ label, exists: !!config?.value }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); + } } - }); + ); - app.get("/system/setting/:label", async (request, response) => { - try { - const { label } = request.params; - if (!SystemSettings.supportedFields.includes(label)) { - response.status(404).json({ label, value: null }); - return; - } + app.get( + "/system/setting/:label", + [validatedRequest], + async (request, response) => { + try { + const { label } = request.params; + if (!SystemSettings.supportedFields.includes(label)) { + response.status(404).json({ label, value: null }); + return; + } - const config = await SystemSettings.get(`label = '${label}'`); - if (SystemSettings.privateField.includes(label)) { - response.status(200).json({ - ...config, - value: new Array((config?.value?.length || 0) + 1).join("*"), - }); - } else { - response.status(200).json(config); + const config = await SystemSettings.get(`label = '${label}'`); + if (SystemSettings.privateField.includes(label)) { + response.status(200).json({ + ...config, + value: new Array((config?.value?.length || 0) + 1).join("*"), + }); + } else { + response.status(200).json(config); + } + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.post("/system/update-settings", async (request, response) => { - try { - const { config } = reqBody(request); - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.post( + "/system/update-settings", + [validatedRequest], + async (request, response) => { + try { + const { config } = reqBody(request); + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + const { success, error } = await SystemSettings.updateSettings(config); + response.status(200).json({ success, error }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - const { success, error } = await SystemSettings.updateSettings(config); - response.status(200).json({ success, error }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); app.get("/boot", async (_, response) => { try { diff --git a/backend/endpoints/v1/document-processor/index.js b/backend/endpoints/v1/document-processor/index.js index fd0d1cb..892d651 100644 --- a/backend/endpoints/v1/document-processor/index.js +++ b/backend/endpoints/v1/document-processor/index.js @@ -1,5 +1,5 @@ const { DocumentProcessor } = require("../../../models/documentProcessor"); -const { userFromSession } = require("../../../utils/http"); +const { userFromSession, validSessionForUser } = require("../../../utils/http"); process.env.NODE_ENV === "development" ? require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }) @@ -8,23 +8,28 @@ process.env.NODE_ENV === "development" function documentProcessorEndpoints(app) { if (!app) return; - app.get("/v1/document-processor/status", async function (request, response) { - try { - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.get( + "/v1/document-processor/status", + [validSessionForUser], + async function (request, response) { + try { + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + const online = await DocumentProcessor.status(); + response.sendStatus(online ? 200 : 503).end(); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - const online = await DocumentProcessor.status(); - response.sendStatus(online ? 200 : 503).end(); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); app.get( "/v1/document-processor/filetypes", + [validSessionForUser], async function (request, response) { try { const user = await userFromSession(request); diff --git a/backend/endpoints/v1/documents/index.js b/backend/endpoints/v1/documents/index.js index 9db8b8b..6585745 100644 --- a/backend/endpoints/v1/documents/index.js +++ b/backend/endpoints/v1/documents/index.js @@ -7,7 +7,11 @@ const { OrganizationWorkspace, } = require("../../../models/organizationWorkspace"); const { WorkspaceDocument } = require("../../../models/workspaceDocument"); -const { userFromSession, reqBody } = require("../../../utils/http"); +const { + userFromSession, + reqBody, + validSessionForUser, +} = require("../../../utils/http"); const { updateEmbeddingJob, } = require("../../../utils/jobs/updateEmbeddingJob"); @@ -26,250 +30,278 @@ process.env.NODE_ENV === "development" function documentEndpoints(app) { if (!app) return; - app.get("/v1/document/:id", async function (request, response) { - try { - const { id } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.get( + "/v1/document/:id", + [validSessionForUser], + async function (request, response) { + try { + const { id } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const document = await WorkspaceDocument.get(`id = ${id}`); + response.status(200).json({ document }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - const document = await WorkspaceDocument.get(`id = ${id}`); - response.status(200).json({ document }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.delete("/v1/document/:id", async function (request, response) { - try { - const { id } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.delete( + "/v1/document/:id", + [validSessionForUser], + async function (request, response) { + try { + const { id } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const document = await WorkspaceDocument.get(`id = ${id}`); + const organization = await Organization.get( + `id = ${document.organization_id}` + ); + const workspace = await OrganizationWorkspace.get( + `id = ${document.workspace_id}` + ); + const connector = await OrganizationConnection.get( + `organization_id = ${organization.id}` + ); + await documentDeletedJob( + organization, + workspace, + document, + connector, + user + ); + response.sendStatus(200).end(); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - const document = await WorkspaceDocument.get(`id = ${id}`); - const organization = await Organization.get( - `id = ${document.organization_id}` - ); - const workspace = await OrganizationWorkspace.get( - `id = ${document.workspace_id}` - ); - const connector = await OrganizationConnection.get( - `organization_id = ${organization.id}` - ); - await documentDeletedJob( - organization, - workspace, - document, - connector, - user - ); - response.sendStatus(200).end(); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.get("/v1/document/:id/fragments", async function (request, response) { - try { - const { id } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.get( + "/v1/document/:id/fragments", + [validSessionForUser], + async function (request, response) { + try { + const { id } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const fragments = await DocumentVectors.where(`document_id = ${id}`); + response.status(200).json({ fragments }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - const fragments = await DocumentVectors.where(`document_id = ${id}`); - response.status(200).json({ fragments }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.post("/v1/document/:id/fragment", async function (request, response) { - try { - const { id } = request.params; - const { newText } = reqBody(request); - const { length, valid } = validEmbedding(newText); + app.post( + "/v1/document/:id/fragment", + [validSessionForUser], + async function (request, response) { + try { + const { id } = request.params; + const { newText } = reqBody(request); + const { length, valid } = validEmbedding(newText); - if (length === 0 || !valid) { - response.status(412).json({ - success: false, - error: "Invalid new text to embed for fragment.", + if (length === 0 || !valid) { + response.status(412).json({ + success: false, + error: "Invalid new text to embed for fragment.", + }); + return; + } + + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const fragment = await DocumentVectors.get(`id = ${id}`); + if (!fragment) { + response.sendStatus(404).end(); + return; + } + + const document = await WorkspaceDocument.get( + `id = ${fragment.document_id}` + ); + const workspace = await OrganizationWorkspace.get( + `id = ${document.workspace_id}` + ); + const organization = await Organization.get( + `id = ${document.organization_id}` + ); + const connector = await OrganizationConnection.get( + `organization_id = ${document.organization_id}` + ); + await updateEmbeddingJob( + fragment, + document, + organization, + workspace, + connector, + user, + newText + ); + response.status(200).json({ success: true, error: null }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); + } + } + ); + + app.delete( + "/v1/document/:id/fragment", + [validSessionForUser], + async function (request, response) { + try { + const { id } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const fragment = await DocumentVectors.get(`id = ${id}`); + if (!fragment) { + response.sendStatus(404).end(); + return; + } + + const document = await WorkspaceDocument.get( + `id = ${fragment.document_id}` + ); + const workspace = await OrganizationWorkspace.get( + `id = ${document.workspace_id}` + ); + const organization = await Organization.get( + `id = ${document.organization_id}` + ); + const connector = await OrganizationConnection.get( + `organization_id = ${document.organization_id}` + ); + await createDeleteEmbeddingJob( + fragment, + workspace, + organization, + connector, + user + ); + response.status(200).json({ success: true, error: null }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); + } + } + ); + + app.get( + "/v1/document/:id/source", + [validSessionForUser], + async function (request, response) { + try { + const { id } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const document = await WorkspaceDocument.get(`id = ${id}`); + const filepath = WorkspaceDocument.vectorFilepath(document); + console.log(filepath); + const source = await readJSON(filepath).then((res) => { + const data = {}; + Object.values(res).map((d) => { + data[d.vectorDbId] = { ...d }; + }); + return data; }); - return; + response.status(200).json({ ...source }); + } catch (e) { + console.log(e); + response.sendStatus(500).end(); } - - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; - } - - const fragment = await DocumentVectors.get(`id = ${id}`); - if (!fragment) { - response.sendStatus(404).end(); - return; - } - - const document = await WorkspaceDocument.get( - `id = ${fragment.document_id}` - ); - const workspace = await OrganizationWorkspace.get( - `id = ${document.workspace_id}` - ); - const organization = await Organization.get( - `id = ${document.organization_id}` - ); - const connector = await OrganizationConnection.get( - `organization_id = ${document.organization_id}` - ); - await updateEmbeddingJob( - fragment, - document, - organization, - workspace, - connector, - user, - newText - ); - response.status(200).json({ success: true, error: null }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.delete("/v1/document/:id/fragment", async function (request, response) { - try { - const { id } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.post( + "/v1/document/:id/clone", + [validSessionForUser], + async function (request, response) { + try { + const { id } = request.params; + const { toWorkspaceId } = reqBody(request); + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const document = await WorkspaceDocument.get(`id = ${id}`); + if (!document) { + response + .status(404) + .json({ success: false, error: "Document does not exist" }); + return; + } + + const workspace = await OrganizationWorkspace.get( + `id = ${toWorkspaceId}` + ); + if (!workspace) { + response.status(404).json({ + success: false, + error: "Destination workspace does not exist", + }); + return; + } + + const organization = await Organization.get( + `id = ${workspace.organization_id}` + ); + const connector = await OrganizationConnection.get( + `organization_id = ${workspace.organization_id}` + ); + if (!connector) { + response.status(404).json({ + success: false, + error: "Organization connector does not exist", + }); + return; + } + + await cloneDocumentJob( + organization, + workspace, + document, + connector, + user + ); + response.status(200).json({ success: true, error: null }); + } catch (e) { + console.log(e); + response.sendStatus(500).end(); } - - const fragment = await DocumentVectors.get(`id = ${id}`); - if (!fragment) { - response.sendStatus(404).end(); - return; - } - - const document = await WorkspaceDocument.get( - `id = ${fragment.document_id}` - ); - const workspace = await OrganizationWorkspace.get( - `id = ${document.workspace_id}` - ); - const organization = await Organization.get( - `id = ${document.organization_id}` - ); - const connector = await OrganizationConnection.get( - `organization_id = ${document.organization_id}` - ); - await createDeleteEmbeddingJob( - fragment, - workspace, - organization, - connector, - user - ); - response.status(200).json({ success: true, error: null }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); - - app.get("/v1/document/:id/source", async function (request, response) { - try { - const { id } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; - } - - const document = await WorkspaceDocument.get(`id = ${id}`); - const filepath = WorkspaceDocument.vectorFilepath(document); - console.log(filepath); - const source = await readJSON(filepath).then((res) => { - const data = {}; - Object.values(res).map((d) => { - data[d.vectorDbId] = { ...d }; - }); - return data; - }); - response.status(200).json({ ...source }); - } catch (e) { - console.log(e); - response.sendStatus(500).end(); - } - }); - - app.post("/v1/document/:id/clone", async function (request, response) { - try { - const { id } = request.params; - const { toWorkspaceId } = reqBody(request); - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; - } - - const document = await WorkspaceDocument.get(`id = ${id}`); - if (!document) { - response - .status(404) - .json({ success: false, error: "Document does not exist" }); - return; - } - - const workspace = await OrganizationWorkspace.get( - `id = ${toWorkspaceId}` - ); - if (!workspace) { - response.status(404).json({ - success: false, - error: "Destination workspace does not exist", - }); - return; - } - - const organization = await Organization.get( - `id = ${workspace.organization_id}` - ); - const connector = await OrganizationConnection.get( - `organization_id = ${workspace.organization_id}` - ); - if (!connector) { - response.status(404).json({ - success: false, - error: "Organization connector does not exist", - }); - return; - } - - await cloneDocumentJob( - organization, - workspace, - document, - connector, - user - ); - response.status(200).json({ success: true, error: null }); - } catch (e) { - console.log(e); - response.sendStatus(500).end(); - } - }); + ); } module.exports = { documentEndpoints }; diff --git a/backend/endpoints/v1/index.js b/backend/endpoints/v1/index.js index 841fd11..474d640 100644 --- a/backend/endpoints/v1/index.js +++ b/backend/endpoints/v1/index.js @@ -1,7 +1,7 @@ process.env.NODE_ENV === "development" ? require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }) : require("dotenv").config(); -const { userFromSession } = require("../../utils/http"); +const { userFromSession, validSessionForUser } = require("../../utils/http"); const { documentProcessorEndpoints } = require("./document-processor"); const { documentEndpoints } = require("./documents"); const { organizationEndpoints } = require("./organizations"); @@ -10,20 +10,24 @@ const { workspaceEndpoints } = require("./workspaces"); function v1Endpoints(app) { if (!app) return; - app.get("/v1/valid-session-token", async function (request, response) { - try { - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; - } + app.get( + "/v1/valid-session-token", + [validSessionForUser], + async function (request, response) { + try { + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } - response.sendStatus(200).end(); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); + response.sendStatus(200).end(); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); + } } - }); + ); userEndpoints(app); organizationEndpoints(app); diff --git a/backend/endpoints/v1/organizations/index.js b/backend/endpoints/v1/organizations/index.js index 9019b33..4e74a63 100644 --- a/backend/endpoints/v1/organizations/index.js +++ b/backend/endpoints/v1/organizations/index.js @@ -9,7 +9,11 @@ const { const { Queue } = require("../../../models/queue"); const { User } = require("../../../models/user"); const { WorkspaceDocument } = require("../../../models/workspaceDocument"); -const { reqBody, userFromSession } = require("../../../utils/http"); +const { + reqBody, + userFromSession, + validSessionForUser, +} = require("../../../utils/http"); const { createSyncJob } = require("../../../utils/jobs/createSyncJob"); const { selectConnector } = require("../../../utils/vectordatabases/providers"); const { @@ -26,213 +30,242 @@ process.env.NODE_ENV === "development" function organizationEndpoints(app) { if (!app) return; - app.post("/v1/org/create", async function (request, response) { - try { - const { orgName } = reqBody(request); - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; - } + app.post( + "/v1/org/create", + [validSessionForUser], + async function (request, response) { + try { + const { orgName } = reqBody(request); + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } - const { organization, message } = await Organization.create( - orgName, - user.id - ); - if (!organization) { - response.status(200).json({ - organization: null, - error: message ?? "Failed to create organization.", - }); - return; - } + const { organization, message } = await Organization.create( + orgName, + user.id + ); + if (!organization) { + response.status(200).json({ + organization: null, + error: message ?? "Failed to create organization.", + }); + return; + } - response.status(200).json({ organization, error: null }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); + response.status(200).json({ organization, error: null }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); + } } - }); + ); - app.get("/v1/orgs", async function (request, response) { - try { - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.get( + "/v1/orgs", + [validSessionForUser], + async function (request, response) { + try { + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + const organizations = await Organization.whereWithOwner( + user.id, + null, + null, + "ORDER BY createdAt ASC" + ); + response.status(200).json({ organizations, error: null }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - const organizations = await Organization.whereWithOwner( - user.id, - null, - null, - "ORDER BY createdAt ASC" - ); - response.status(200).json({ organizations, error: null }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.get("/v1/orgs/all", async function (request, response) { - try { - const user = await userFromSession(request); - if (!user || user.role !== "admin") { - response.sendStatus(403).end(); - return; + app.get( + "/v1/orgs/all", + [validSessionForUser], + async function (request, response) { + try { + const user = await userFromSession(request); + if (!user || user.role !== "admin") { + response.sendStatus(403).end(); + return; + } + const organizations = await Organization.where(`id IS NOT NULL`); + response.status(200).json({ organizations, error: null }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - const organizations = await Organization.where(`id IS NOT NULL`); - response.status(200).json({ organizations, error: null }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.get("/v1/org/:slug", async function (request, response) { - try { - const { slug } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; - } - const organization = await Organization.getWithOwner( - user.id, - `slug = '${slug}'` - ); - if (!organization) { - response - .status(200) - .json({ organization: null, error: "No org by that slug." }); - return; - } + app.get( + "/v1/org/:slug", + [validSessionForUser], + async function (request, response) { + try { + const { slug } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + const organization = await Organization.getWithOwner( + user.id, + `slug = '${slug}'` + ); + if (!organization) { + response + .status(200) + .json({ organization: null, error: "No org by that slug." }); + return; + } - response.status(200).json({ organization, error: null }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); + response.status(200).json({ organization, error: null }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); + } } - }); + ); - app.get("/v1/org/:slug/api-key", async function (request, response) { - try { - const { slug } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.get( + "/v1/org/:slug/api-key", + [validSessionForUser], + async function (request, response) { + try { + const { slug } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const organization = await Organization.getWithOwner( + user.id, + `slug = '${slug}'` + ); + if (!organization) { + response + .status(200) + .json({ organization: null, error: "No org by that slug." }); + return; + } + + const apiKey = await OrganizationApiKey.get( + `organization_id = ${organization.id}` + ); + if (!apiKey) { + response.status(200).json({ + organization: null, + error: "No api key for that organization.", + }); + return; + } + + response.status(200).json({ apiKey, error: null }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - const organization = await Organization.getWithOwner( - user.id, - `slug = '${slug}'` - ); - if (!organization) { - response - .status(200) - .json({ organization: null, error: "No org by that slug." }); - return; - } - - const apiKey = await OrganizationApiKey.get( - `organization_id = ${organization.id}` - ); - if (!apiKey) { - response.status(200).json({ - organization: null, - error: "No api key for that organization.", - }); - return; - } - - response.status(200).json({ apiKey, error: null }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.get("/v1/org/:slug/connection", async function (request, response) { - try { - const { slug } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.get( + "/v1/org/:slug/connection", + [validSessionForUser], + async function (request, response) { + try { + const { slug } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const organization = await Organization.getWithOwner( + user.id, + `slug = '${slug}'` + ); + if (!organization) { + response + .status(200) + .json({ organization: null, error: "No org by that slug." }); + return; + } + + const connector = await OrganizationConnection.get( + `organization_id = ${organization.id}` + ); + if (!connector) { + response.status(200).json({ + connector: null, + error: "No data connector for that organization.", + }); + return; + } + + response.status(200).json({ connector, error: null }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - const organization = await Organization.getWithOwner( - user.id, - `slug = '${slug}'` - ); - if (!organization) { - response - .status(200) - .json({ organization: null, error: "No org by that slug." }); - return; - } - - const connector = await OrganizationConnection.get( - `organization_id = ${organization.id}` - ); - if (!connector) { - response.status(200).json({ - connector: null, - error: "No data connector for that organization.", - }); - return; - } - - response.status(200).json({ connector, error: null }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.post("/v1/org/:slug/add-connection", async function (request, response) { - try { - const { slug } = request.params; - const { config } = reqBody(request); - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.post( + "/v1/org/:slug/add-connection", + [validSessionForUser], + async function (request, response) { + try { + const { slug } = request.params; + const { config } = reqBody(request); + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const organization = await Organization.getWithOwner( + user.id, + `slug = '${slug}'` + ); + if (!organization) { + response + .status(200) + .json({ organization: null, error: "No org by that slug." }); + return; + } + + const connector = await OrganizationConnection.get( + `organization_id = ${organization.id}` + ); + if (!!connector) { + response.status(200).json({ + connector: null, + error: "Vector database connector already exists for organization.", + }); + return; + } + + const result = await validateNewDatabaseConnector(organization, config); + response.status(200).json(result); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - const organization = await Organization.getWithOwner( - user.id, - `slug = '${slug}'` - ); - if (!organization) { - response - .status(200) - .json({ organization: null, error: "No org by that slug." }); - return; - } - - const connector = await OrganizationConnection.get( - `organization_id = ${organization.id}` - ); - if (!!connector) { - response.status(200).json({ - connector: null, - error: "Vector database connector already exists for organization.", - }); - return; - } - - const result = await validateNewDatabaseConnector(organization, config); - response.status(200).json(result); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); app.post( "/v1/org/:slug/update-connection", + [validSessionForUser], async function (request, response) { try { const { slug } = request.params; @@ -279,6 +312,7 @@ function organizationEndpoints(app) { app.post( "/v1/org/:slug/connector/:command", + [validSessionForUser], async function (request, response) { try { const { slug, command } = request.params; @@ -323,6 +357,7 @@ function organizationEndpoints(app) { app.get( "/v1/org/:slug/connector/:connectorId/sync", + [validSessionForUser], async function (request, response) { try { const { slug, connectorId } = request.params; @@ -360,106 +395,119 @@ function organizationEndpoints(app) { } ); - app.get("/v1/org/:slug/workspaces", async function (request, response) { - try { - const { slug } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; - } + app.get( + "/v1/org/:slug/workspaces", + [validSessionForUser], + async function (request, response) { + try { + const { slug } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } - const organization = await Organization.getWithOwner( - user.id, - `slug = '${slug}'` - ); - if (!organization) { - response - .status(200) - .json({ organization: null, error: "No org found." }); - return; - } + const organization = await Organization.getWithOwner( + user.id, + `slug = '${slug}'` + ); + if (!organization) { + response + .status(200) + .json({ organization: null, error: "No org found." }); + return; + } - const workspaces = await OrganizationWorkspace.forOrganization( - organization.id - ); - response.status(200).json({ workspaces }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); + const workspaces = await OrganizationWorkspace.forOrganization( + organization.id + ); + response.status(200).json({ workspaces }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); + } } - }); + ); - app.get("/v1/org/:slug/jobs", async function (request, response) { - try { - const { slug } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; - } + app.get( + "/v1/org/:slug/jobs", + [validSessionForUser], + async function (request, response) { + try { + const { slug } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } - const organization = await Organization.getWithOwner( - user.id, - `slug = '${slug}'` - ); - if (!organization) { - response - .status(200) - .json({ organization: null, error: "No org found." }); - return; - } + const organization = await Organization.getWithOwner( + user.id, + `slug = '${slug}'` + ); + if (!organization) { + response + .status(200) + .json({ organization: null, error: "No org found." }); + return; + } - const jobs = await Queue.where( - `organizationId = ${organization.id}`, - null, - "ORDER BY createdAt DESC" - ); - for (const job of jobs) { - const { id, email, role } = await User.get(`id = ${job.runByUserId}`); - job.runByUser = { id, email, role }; + const jobs = await Queue.where( + `organizationId = ${organization.id}`, + null, + "ORDER BY createdAt DESC" + ); + for (const job of jobs) { + const { id, email, role } = await User.get(`id = ${job.runByUserId}`); + job.runByUser = { id, email, role }; + } + response.status(200).json({ jobs }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - response.status(200).json({ jobs }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.get("/v1/org/:slug/documents", async function (request, response) { - try { - const { slug } = request.params; - const user = await userFromSession(request); - if (!user) { - response.sendStatus(403).end(); - return; + app.get( + "/v1/org/:slug/documents", + [validSessionForUser], + async function (request, response) { + try { + const { slug } = request.params; + const user = await userFromSession(request); + if (!user) { + response.sendStatus(403).end(); + return; + } + + const organization = await Organization.getWithOwner( + user.id, + `slug = '${slug}'` + ); + if (!organization) { + response + .status(200) + .json({ organization: null, error: "No org found." }); + return; + } + + const documents = await WorkspaceDocument.where( + `organization_id = ${organization.id}`, + null, + true + ); + response.status(200).json({ documents }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - const organization = await Organization.getWithOwner( - user.id, - `slug = '${slug}'` - ); - if (!organization) { - response - .status(200) - .json({ organization: null, error: "No org found." }); - return; - } - - const documents = await WorkspaceDocument.where( - `organization_id = ${organization.id}`, - null, - true - ); - response.status(200).json({ documents }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); app.get( "/v1/org/:slug/statistics/:statistic", + [validSessionForUser], async function (request, response) { try { const { slug, statistic } = request.params; diff --git a/backend/endpoints/v1/users/index.js b/backend/endpoints/v1/users/index.js index 4963083..8b7a2ce 100644 --- a/backend/endpoints/v1/users/index.js +++ b/backend/endpoints/v1/users/index.js @@ -1,5 +1,9 @@ const { User } = require("../../../models/user"); -const { userFromSession, reqBody } = require("../../../utils/http"); +const { + userFromSession, + reqBody, + validSessionForUser, +} = require("../../../utils/http"); process.env.NODE_ENV === "development" ? require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }) @@ -8,86 +12,102 @@ process.env.NODE_ENV === "development" function userEndpoints(app) { if (!app) return; - app.get("/v1/users", async function (request, response) { - try { - const user = await userFromSession(request); - if (!user || user.role !== "admin") { - response.sendStatus(403).end(); - return; - } + app.get( + "/v1/users", + [validSessionForUser], + async function (request, response) { + try { + const user = await userFromSession(request); + if (!user || user.role !== "admin") { + response.sendStatus(403).end(); + return; + } - const users = await User.whereWithOrgs(`role != 'root'`); - response.status(200).json({ users }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); + const users = await User.whereWithOrgs(`role != 'root'`); + response.status(200).json({ users }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); + } } - }); + ); - app.delete("/v1/users/:userId", async function (request, response) { - try { - const { userId } = request.params; - const user = await userFromSession(request); - if (!user || user.role !== "admin") { - response.sendStatus(403).end(); - return; + app.delete( + "/v1/users/:userId", + [validSessionForUser], + async function (request, response) { + try { + const { userId } = request.params; + const user = await userFromSession(request); + if (!user || user.role !== "admin") { + response.sendStatus(403).end(); + return; + } + + if (user.id == userId) { + response + .status(200) + .json({ success: false, error: "You cannot delete yourself." }); + return; + } + + await User.delete(`id = ${userId}`); + response.status(200).json({ success: true, error: null }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - if (user.id == userId) { - response - .status(200) - .json({ success: false, error: "You cannot delete yourself." }); - return; - } - - await User.delete(`id = ${userId}`); - response.status(200).json({ success: true, error: null }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.post("/v1/user/new", async function (request, response) { - try { - const { email, password, role = "default" } = reqBody(request); - const user = await userFromSession(request); - if (!user || user.role !== "admin") { - response.sendStatus(403).end(); - return; + app.post( + "/v1/user/new", + [validSessionForUser], + async function (request, response) { + try { + const { email, password, role = "default" } = reqBody(request); + const user = await userFromSession(request); + if (!user || user.role !== "admin") { + response.sendStatus(403).end(); + return; + } + + const { user: newUser, message } = await User.create({ + email, + password, + role, + }); + await User.addToAllOrgs(newUser.id); + response.status(200).json({ success: !!newUser, error: message }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - const { user: newUser, message } = await User.create({ - email, - password, - role, - }); - await User.addToAllOrgs(newUser.id); - response.status(200).json({ success: !!newUser, error: message }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); - app.post("/v1/users/:userId", async function (request, response) { - try { - const { userId } = request.params; - const updates = reqBody(request); + app.post( + "/v1/users/:userId", + [validSessionForUser], + async function (request, response) { + try { + const { userId } = request.params; + const updates = reqBody(request); - const user = await userFromSession(request); - if (!user || user.role !== "admin") { - response.sendStatus(403).end(); - return; + const user = await userFromSession(request); + if (!user || user.role !== "admin") { + response.sendStatus(403).end(); + return; + } + + const { success, error } = await User.update(userId, updates); + response.status(200).json({ success, error }); + } catch (e) { + console.log(e.message, e); + response.sendStatus(500).end(); } - - const { success, error } = await User.update(userId, updates); - response.status(200).json({ success, error }); - } catch (e) { - console.log(e.message, e); - response.sendStatus(500).end(); } - }); + ); } module.exports = { userEndpoints }; diff --git a/backend/endpoints/v1/workspaces/index.js b/backend/endpoints/v1/workspaces/index.js index c8ceaf5..040ccfd 100644 --- a/backend/endpoints/v1/workspaces/index.js +++ b/backend/endpoints/v1/workspaces/index.js @@ -6,7 +6,11 @@ const { OrganizationWorkspace, } = require("../../../models/organizationWorkspace"); const { WorkspaceDocument } = require("../../../models/workspaceDocument"); -const { userFromSession, reqBody } = require("../../../utils/http"); +const { + userFromSession, + reqBody, + validSessionForUser, +} = require("../../../utils/http"); const { setupMulter } = require("../../..//utils/files/multer"); const { DocumentProcessor } = require("../../../models/documentProcessor"); const { addDocumentJob } = require("../../../utils/jobs/addDocumentsJob"); @@ -29,6 +33,7 @@ function workspaceEndpoints(app) { app.post( "/v1/org/:orgSlug/new-workspace", + [validSessionForUser], async function (request, response) { try { const { orgSlug } = request.params; @@ -79,6 +84,7 @@ function workspaceEndpoints(app) { app.get( "/v1/org/:orgSlug/workspace/:wsSlug", + [validSessionForUser], async function (request, response) { try { const { orgSlug, wsSlug } = request.params; @@ -110,6 +116,7 @@ function workspaceEndpoints(app) { app.delete( "/v1/org/:orgSlug/workspace/:wsSlug", + [validSessionForUser], async function (request, response) { try { const { orgSlug, wsSlug } = request.params; @@ -163,6 +170,7 @@ function workspaceEndpoints(app) { app.get( "/v1/org/:orgSlug/workspace/:wsSlug/documents", + [validSessionForUser], async function (request, response) { try { const { orgSlug, wsSlug } = request.params; @@ -201,6 +209,7 @@ function workspaceEndpoints(app) { app.get( "/v1/org/:slug/workspace/:workspaceSlug/statistics/:statistic", + [validSessionForUser], async function (request, response) { try { const { slug, workspaceSlug, statistic } = request.params; @@ -339,6 +348,7 @@ function workspaceEndpoints(app) { app.get( "/v1/org/:slug/connector/:connectorId/sync/:workspaceSlug", + [validSessionForUser], async function (request, response) { try { const { slug, workspaceSlug, connectorId } = request.params; diff --git a/backend/index.js b/backend/index.js index 63b0aef..d08981d 100644 --- a/backend/index.js +++ b/backend/index.js @@ -25,12 +25,10 @@ app.use( }) ); -authenticationEndpoints(app); -apiRouter.use("/system/*", validatedRequest); -systemEndpoints(app); - -apiRouter.use("/v1/*", validSessionForUser); -v1Endpoints(app); +app.use("/api", apiRouter); +authenticationEndpoints(apiRouter); +systemEndpoints(apiRouter); +v1Endpoints(apiRouter); if (process.env.NODE_ENV !== "development") { app.use( diff --git a/frontend/src/utils/constants.ts b/frontend/src/utils/constants.ts index f6b60c1..c47b23c 100644 --- a/frontend/src/utils/constants.ts +++ b/frontend/src/utils/constants.ts @@ -1,5 +1,5 @@ export const API_BASE = - import.meta.env.VITE_API_BASE || 'http://127.0.0.1:3001'; + import.meta.env.VITE_API_BASE || 'http://127.0.0.1:3001/api'; export const APP_NAME = import.meta.env.VITE_APP_NAME || 'VDMS'; export const STORE_USER = 'vdms_user'; export const STORE_TOKEN = 'vdms_authToken';