diff --git a/front/lib/api/data_sources.ts b/front/lib/api/data_sources.ts index ed319600b1e9..18952115e72e 100644 --- a/front/lib/api/data_sources.ts +++ b/front/lib/api/data_sources.ts @@ -1,8 +1,21 @@ -import { DataSourceType } from "@dust-tt/types"; +import { + APIError, + ConnectorProvider, + ConnectorsAPI, + CoreAPI, + DataSourceType, + Err, + Ok, + Result, +} from "@dust-tt/types"; import { Op } from "sequelize"; +import { getMembers } from "@app/lib/api/workspace"; import { Authenticator } from "@app/lib/auth"; +import { sendGithubDeletionEmail } from "@app/lib/email"; import { DataSource } from "@app/lib/models"; +import logger from "@app/logger/logger"; +import { launchScrubDataSourceWorkflow } from "@app/poke/temporal/client"; export async function getDataSource( auth: Authenticator, @@ -83,3 +96,94 @@ export async function getDataSources( }; }); } +export async function deleteDataSource( + auth: Authenticator, + dataSourceName: string +): Promise> { + const workspace = auth.workspace(); + if (!workspace) { + return new Err({ + type: "workspace_not_found", + message: "Could not find the workspace.", + }); + } + if (!auth.isAdmin()) { + return new Err({ + type: "workspace_auth_error", + message: + "Only users that are `admins` for the current workspace can delete data sources.", + }); + } + const dataSource = await DataSource.findOne({ + where: { + workspaceId: workspace.id, + name: dataSourceName, + }, + }); + if (!dataSource) { + return new Err({ + type: "data_source_not_found", + message: "Could not find the data source.", + }); + } + + const dustAPIProjectId = dataSource.dustAPIProjectId; + + const connectorsAPI = new ConnectorsAPI(logger); + if (dataSource.connectorId) { + const connDeleteRes = await connectorsAPI.deleteConnector( + dataSource.connectorId.toString(), + true + ); + if (connDeleteRes.isErr()) { + // If we get a not found we proceed with the deletion of the data source. This will enable + // us to retry deletion of the data source if it fails at the Core level. + if (connDeleteRes.error.error.type !== "connector_not_found") { + return new Err({ + type: "internal_server_error", + message: `Error deleting connector: ${connDeleteRes.error.error.message}`, + }); + } + } + } + + const coreAPI = new CoreAPI(logger); + const coreDeleteRes = await coreAPI.deleteDataSource({ + projectId: dustAPIProjectId, + dataSourceName: dataSource.name, + }); + if (coreDeleteRes.isErr()) { + return new Err({ + type: "internal_server_error", + message: `Error deleting core data source: ${coreDeleteRes.error.message}`, + }); + } + + await dataSource.destroy(); + + await launchScrubDataSourceWorkflow({ + wId: workspace.sId, + dustAPIProjectId, + }); + if (dataSource.connectorProvider) + await warnPostDeletion(auth, dataSource.connectorProvider); + + return new Ok({ success: true }); +} + +async function warnPostDeletion( + auth: Authenticator, + dataSourceProvider: ConnectorProvider +) { + // if the datasource is Github, send an email inviting to delete the Github app + switch (dataSourceProvider) { + case "github": + // get admin emails + const adminEmails = (await getMembers(auth, "admin")).map((u) => u.email); + // send email to admins + for (const email of adminEmails) await sendGithubDeletionEmail(email); + break; + default: + break; + } +} diff --git a/front/lib/data_sources.ts b/front/lib/data_sources.ts index 285db818a6de..96876775282b 100644 --- a/front/lib/data_sources.ts +++ b/front/lib/data_sources.ts @@ -1,21 +1,4 @@ -import { - APIError, - ConnectorProvider, - ConnectorsAPI, - CoreAPI, - CoreAPIDocument, - DataSourceType, - Err, - Ok, - Result, -} from "@dust-tt/types"; - -import { getMembers } from "@app/lib/api/workspace"; -import { Authenticator } from "@app/lib/auth"; -import { sendGithubDeletionEmail } from "@app/lib/email"; -import { DataSource } from "@app/lib/models"; -import logger from "@app/logger/logger"; -import { launchScrubDataSourceWorkflow } from "@app/poke/temporal/client"; +import { CoreAPIDocument, DataSourceType } from "@dust-tt/types"; export function getProviderLogoPathForDataSource( ds: DataSourceType @@ -57,95 +40,3 @@ export function getDisplayNameForDocument(document: CoreAPIDocument): string { } return titleTag.substring(titleTagPrefix.length); } - -export async function deleteDataSource( - auth: Authenticator, - dataSourceName: string -): Promise> { - const workspace = auth.workspace(); - if (!workspace) { - return new Err({ - type: "workspace_not_found", - message: "Could not find the workspace.", - }); - } - if (!auth.isAdmin()) { - return new Err({ - type: "workspace_auth_error", - message: - "Only users that are `admins` for the current workspace can delete data sources.", - }); - } - const dataSource = await DataSource.findOne({ - where: { - workspaceId: workspace.id, - name: dataSourceName, - }, - }); - if (!dataSource) { - return new Err({ - type: "data_source_not_found", - message: "Could not find the data source.", - }); - } - - const dustAPIProjectId = dataSource.dustAPIProjectId; - - const connectorsAPI = new ConnectorsAPI(logger); - if (dataSource.connectorId) { - const connDeleteRes = await connectorsAPI.deleteConnector( - dataSource.connectorId.toString(), - true - ); - if (connDeleteRes.isErr()) { - // If we get a not found we proceed with the deletion of the data source. This will enable - // us to retry deletion of the data source if it fails at the Core level. - if (connDeleteRes.error.error.type !== "connector_not_found") { - return new Err({ - type: "internal_server_error", - message: `Error deleting connector: ${connDeleteRes.error.error.message}`, - }); - } - } - } - - const coreAPI = new CoreAPI(logger); - const coreDeleteRes = await coreAPI.deleteDataSource({ - projectId: dustAPIProjectId, - dataSourceName: dataSource.name, - }); - if (coreDeleteRes.isErr()) { - return new Err({ - type: "internal_server_error", - message: `Error deleting core data source: ${coreDeleteRes.error.message}`, - }); - } - - await dataSource.destroy(); - - await launchScrubDataSourceWorkflow({ - wId: workspace.sId, - dustAPIProjectId, - }); - if (dataSource.connectorProvider) - await warnPostDeletion(auth, dataSource.connectorProvider); - - return new Ok({ success: true }); -} - -async function warnPostDeletion( - auth: Authenticator, - dataSourceProvider: ConnectorProvider -) { - // if the datasource is Github, send an email inviting to delete the Github app - switch (dataSourceProvider) { - case "github": - // get admin emails - const adminEmails = (await getMembers(auth, "admin")).map((u) => u.email); - // send email to admins - for (const email of adminEmails) await sendGithubDeletionEmail(email); - break; - default: - break; - } -} diff --git a/front/lib/email.ts b/front/lib/email.ts index 37a6bbd0bfa8..ce21d1685290 100644 --- a/front/lib/email.ts +++ b/front/lib/email.ts @@ -7,11 +7,8 @@ import sgMail from "@sendgrid/mail"; import { XP1User } from "@app/lib/models"; import logger from "@app/logger/logger"; -const { SENDGRID_API_KEY, XP1_CHROME_WEB_STORE_URL } = process.env; +const { SENDGRID_API_KEY = "", XP1_CHROME_WEB_STORE_URL } = process.env; -if (!SENDGRID_API_KEY) { - throw new Error("Missing SENDGRID_API_KEY env variable"); -} sgMail.setApiKey(SENDGRID_API_KEY); export async function sendEmail(email: string, message: any) { diff --git a/front/pages/api/poke/workspaces/[wId]/data_sources/[name]/index.ts b/front/pages/api/poke/workspaces/[wId]/data_sources/[name]/index.ts index 8eb863ca3514..b3257005a374 100644 --- a/front/pages/api/poke/workspaces/[wId]/data_sources/[name]/index.ts +++ b/front/pages/api/poke/workspaces/[wId]/data_sources/[name]/index.ts @@ -1,8 +1,8 @@ import { ReturnedAPIErrorType } from "@dust-tt/types"; import { NextApiRequest, NextApiResponse } from "next"; +import { deleteDataSource } from "@app/lib/api/data_sources"; import { Authenticator, getSession } from "@app/lib/auth"; -import { deleteDataSource } from "@app/lib/data_sources"; import { apiError, withLogging } from "@app/logger/withlogging"; export type DeleteDataSourceResponseBody = { diff --git a/front/pages/api/stripe/webhook.ts b/front/pages/api/stripe/webhook.ts index e8794c461804..d3ab0f3a483a 100644 --- a/front/pages/api/stripe/webhook.ts +++ b/front/pages/api/stripe/webhook.ts @@ -13,9 +13,9 @@ import { getAgentConfigurations, } from "@app/lib/api/assistant/configuration"; import { getDataSources } from "@app/lib/api/data_sources"; +import { deleteDataSource } from "@app/lib/api/data_sources"; import { getMembers } from "@app/lib/api/workspace"; import { Authenticator } from "@app/lib/auth"; -import { deleteDataSource } from "@app/lib/data_sources"; import { front_sequelize } from "@app/lib/databases"; import { sendAdminDowngradeTooMuchDataEmail,