From 8987938642cee5c99eab86cd498d1bb926627872 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Fri, 25 Apr 2025 11:03:31 +0400 Subject: [PATCH] fix(microsoft-teams-integration): bug fixes --- ...35_microsoft-teams-workflow-integration.ts | 3 + .../schemas/microsoft-teams-integrations.ts | 2 + .../trigger-notification.ts | 8 +- .../microsoft-teams/microsoft-teams-fns.ts | 290 +++++++++++++----- .../microsoft-teams-service.ts | 121 ++++++-- .../microsoft-teams/microsoft-teams-types.ts | 2 + .../AddWorkflowIntegrationModal.tsx | 7 +- .../EditWorkflowIntegrationModal.tsx | 4 + .../MicrosoftTeamsIntegrationForm.tsx | 8 +- 9 files changed, 332 insertions(+), 113 deletions(-) diff --git a/backend/src/db/migrations/20250422125635_microsoft-teams-workflow-integration.ts b/backend/src/db/migrations/20250422125635_microsoft-teams-workflow-integration.ts index 0b3a55ad4..ed1b9333c 100644 --- a/backend/src/db/migrations/20250422125635_microsoft-teams-workflow-integration.ts +++ b/backend/src/db/migrations/20250422125635_microsoft-teams-workflow-integration.ts @@ -51,6 +51,9 @@ export async function up(knex: Knex): Promise { table.binary("encryptedAccessToken").nullable(); table.binary("encryptedBotAccessToken").nullable(); + table.timestamp("accessTokenExpiresAt").nullable(); + table.timestamp("botAccessTokenExpiresAt").nullable(); + table.timestamps(true, true, true); }); diff --git a/backend/src/db/schemas/microsoft-teams-integrations.ts b/backend/src/db/schemas/microsoft-teams-integrations.ts index d0a89429d..36aae5f78 100644 --- a/backend/src/db/schemas/microsoft-teams-integrations.ts +++ b/backend/src/db/schemas/microsoft-teams-integrations.ts @@ -15,6 +15,8 @@ export const MicrosoftTeamsIntegrationsSchema = z.object({ tenantId: z.string(), encryptedAccessToken: zodBuffer.nullable().optional(), encryptedBotAccessToken: zodBuffer.nullable().optional(), + accessTokenExpiresAt: z.date().nullable().optional(), + botAccessTokenExpiresAt: z.date().nullable().optional(), createdAt: z.date(), updatedAt: z.date() }); diff --git a/backend/src/lib/workflow-integrations/trigger-notification.ts b/backend/src/lib/workflow-integrations/trigger-notification.ts index 1cadb6aa6..58411bdb0 100644 --- a/backend/src/lib/workflow-integrations/trigger-notification.ts +++ b/backend/src/lib/workflow-integrations/trigger-notification.ts @@ -61,7 +61,9 @@ export const triggerWorkflowIntegrationNotification = async (dto: TTriggerWorkfl .sendNotification({ notification, target: data, - tenantId: microsoftTeamsConfig.tenantId + tenantId: microsoftTeamsConfig.tenantId, + microsoftTeamsIntegrationId: microsoftTeamsConfig.id, + orgId: project.orgId }) .catch((error) => { logger.error(error, "Error sending Microsoft Teams notification"); @@ -79,7 +81,9 @@ export const triggerWorkflowIntegrationNotification = async (dto: TTriggerWorkfl .sendNotification({ notification, target: data, - tenantId: microsoftTeamsConfig.tenantId + tenantId: microsoftTeamsConfig.tenantId, + microsoftTeamsIntegrationId: microsoftTeamsConfig.id, + orgId: project.orgId }) .catch((error) => { logger.error(error, "Error sending Microsoft Teams notification"); diff --git a/backend/src/services/microsoft-teams/microsoft-teams-fns.ts b/backend/src/services/microsoft-teams/microsoft-teams-fns.ts index d8986625d..e6173e21b 100644 --- a/backend/src/services/microsoft-teams/microsoft-teams-fns.ts +++ b/backend/src/services/microsoft-teams/microsoft-teams-fns.ts @@ -1,6 +1,7 @@ /* eslint-disable class-methods-use-this */ import axios from "axios"; import { TeamsActivityHandler, TurnContext } from "botbuilder"; +import { Knex } from "knex"; import { z } from "zod"; import { getConfig } from "@app/lib/config/env"; @@ -8,68 +9,218 @@ import { BadRequestError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; import { TNotification, TriggerFeature } from "@app/lib/workflow-integrations/types"; +import { TKmsServiceFactory } from "../kms/kms-service"; +import { KmsDataKey } from "../kms/kms-types"; import { TWorkflowIntegrationDALFactory } from "../workflow-integration/workflow-integration-dal"; import { WorkflowIntegrationStatus } from "../workflow-integration/workflow-integration-types"; import { TMicrosoftTeamsIntegrationDALFactory } from "./microsoft-teams-integration-dal"; -export const getMicrosoftTeamsAccessToken = async ({ - tenantId, - clientId, - clientSecret, - getBotFrameworkToken = false -}: { - tenantId: string; - clientId: string; - clientSecret: string; - getBotFrameworkToken?: boolean; -}) => { - const details = getBotFrameworkToken - ? { - uri: "https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token", - scope: "https://api.botframework.com/.default" +export const getMicrosoftTeamsAccessToken = async ( + { + orgId, + microsoftTeamsIntegrationId, + tenantId, + clientId, + clientSecret, + kmsService, + microsoftTeamsIntegrationDAL, + getBotFrameworkToken + }: { + microsoftTeamsIntegrationId: string; + orgId: string; + tenantId: string; + clientId: string; + clientSecret: string; + kmsService: Pick; + microsoftTeamsIntegrationDAL: Pick; + getBotFrameworkToken?: boolean; + }, + tx?: Knex +) => { + try { + const details = getBotFrameworkToken + ? { + uri: "https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token", + scope: "https://api.botframework.com/.default" + } + : { + uri: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`, + scope: "https://graph.microsoft.com/.default" + }; + + const integration = await microsoftTeamsIntegrationDAL.findOne( + { + id: microsoftTeamsIntegrationId + }, + tx + ); + + if (!integration) { + throw new BadRequestError({ message: "Microsoft Teams integration not found" }); + } + + if (getBotFrameworkToken) { + const currentTime = new Date(new Date().getTime() + 5 * 60 * 1000); + + if ( + integration.encryptedBotAccessToken && + integration.botAccessTokenExpiresAt && + integration.botAccessTokenExpiresAt > currentTime + ) { + const { decryptor } = await kmsService.createCipherPairWithDataKey({ + orgId, + type: KmsDataKey.Organization + }); + + const botAccessToken = decryptor({ + cipherTextBlob: integration.encryptedBotAccessToken + }); + + return botAccessToken.toString(); } - : { - uri: `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`, - scope: "https://graph.microsoft.com/.default" - }; + } else { + const currentTime = new Date(new Date().getTime() + 5 * 60 * 1000); - const tokenResponse = await axios.post<{ access_token: string }>( - details.uri, - new URLSearchParams({ - client_id: clientId, - client_secret: clientSecret, - scope: details.scope, - grant_type: "client_credentials" - }) - ); + if ( + integration.encryptedAccessToken && + integration.accessTokenExpiresAt && + integration.accessTokenExpiresAt > currentTime + ) { + const { decryptor } = await kmsService.createCipherPairWithDataKey({ + orgId, + type: KmsDataKey.Organization + }); - return tokenResponse.data.access_token; + const accessToken = decryptor({ + cipherTextBlob: integration.encryptedAccessToken + }); + + return accessToken.toString(); + } + } + + const tokenResponse = await axios.post<{ access_token: string; expires_in: number }>( + details.uri, + new URLSearchParams({ + client_id: clientId, + client_secret: clientSecret, + scope: details.scope, + grant_type: "client_credentials" + }) + ); + + if (getBotFrameworkToken) { + const { encryptor } = await kmsService.createCipherPairWithDataKey({ + orgId, + type: KmsDataKey.Organization + }); + + const { cipherTextBlob: encryptedBotAccessToken } = encryptor({ + plainText: Buffer.from(tokenResponse.data.access_token) + }); + + const expiresAt = new Date(new Date().getTime() + tokenResponse.data.expires_in * 1000); + + await microsoftTeamsIntegrationDAL.update( + { + id: microsoftTeamsIntegrationId + }, + { + botAccessTokenExpiresAt: expiresAt, + encryptedBotAccessToken + }, + tx + ); + } else { + const { encryptor } = await kmsService.createCipherPairWithDataKey({ + orgId, + type: KmsDataKey.Organization + }); + + const { cipherTextBlob: encryptedAccessToken } = encryptor({ + plainText: Buffer.from(tokenResponse.data.access_token) + }); + + const expiresAt = new Date(new Date().getTime() + tokenResponse.data.expires_in * 1000); + + await microsoftTeamsIntegrationDAL.update( + { + id: microsoftTeamsIntegrationId + }, + { + accessTokenExpiresAt: expiresAt, + encryptedAccessToken + }, + tx + ); + } + + return tokenResponse.data.access_token; + } catch (error) { + if (axios.isAxiosError(error)) { + logger.error( + error.response?.data, + `getMicrosoftTeamsAccessToken: Error fetching Microsoft Teams access token [status-code=${error.response?.status}]` + ); + } else { + logger.error(error, "getMicrosoftTeamsAccessToken: Error fetching Microsoft Teams access token"); + } + throw error; + } }; -export const isBotInstalledInTenant = async ({ - tenantId, - botAppId, - botAppPassword, - botId -}: { - tenantId: string; - botAppId: string; - botAppPassword: string; - botId: string; -}) => { +export const isBotInstalledInTenant = async ( + { + tenantId, + botAppId, + botAppPassword, + botId, + orgId, + kmsService, + microsoftTeamsIntegrationDAL, + microsoftTeamsIntegrationId + }: { + tenantId: string; + botAppId: string; + botAppPassword: string; + botId: string; + orgId: string; + kmsService: Pick; + microsoftTeamsIntegrationDAL: Pick; + microsoftTeamsIntegrationId: string; + }, + tx?: Knex +) => { try { - const botAccessToken = await getMicrosoftTeamsAccessToken({ - tenantId, - clientId: botAppId.toString(), - clientSecret: botAppPassword.toString(), - getBotFrameworkToken: true - }).catch(() => null); + const botAccessToken = await getMicrosoftTeamsAccessToken( + { + tenantId, + clientId: botAppId.toString(), + clientSecret: botAppPassword.toString(), + getBotFrameworkToken: true, + orgId, + kmsService, + microsoftTeamsIntegrationDAL, + microsoftTeamsIntegrationId + }, + tx + ).catch(() => null); - const accessToken = await getMicrosoftTeamsAccessToken({ - tenantId, - clientId: botAppId.toString(), - clientSecret: botAppPassword.toString() - }).catch(() => null); + const accessToken = await getMicrosoftTeamsAccessToken( + { + orgId, + tenantId, + clientId: botAppId.toString(), + clientSecret: botAppPassword.toString(), + kmsService, + microsoftTeamsIntegrationDAL, + microsoftTeamsIntegrationId + }, + tx + ).catch(() => null); + + console.log("botAccessToken", botAccessToken); + console.log("accessToken", accessToken); if (!botAccessToken || !accessToken) { return { @@ -105,6 +256,12 @@ export const isBotInstalledInTenant = async ({ const botInstalledInTenant = appsResponse.data.value.find((a) => a.externalId === botId); + for (const app of appsResponse.data.value) { + if (app.displayName.toLowerCase().includes("infisical")) { + console.log(`${app.displayName} - ${app.externalId}`); + } + } + if (!botInstalledInTenant) { return { installed: false, @@ -311,17 +468,16 @@ export class TeamsBot extends TeamsActivityHandler { await super.run(context); } - async sendMessageToChannel(tenantId: string, channelId: string, teamId: string, notification: TNotification) { + async sendMessageToChannel( + botAccessToken: string, + tenantId: string, + channelId: string, + teamId: string, + notification: TNotification + ) { try { const { adaptiveCard } = buildTeamsPayload(notification); - const botToken = await getMicrosoftTeamsAccessToken({ - tenantId, - clientId: this.botAppId, - clientSecret: this.botAppPassword, - getBotFrameworkToken: true - }); - const adaptiveCardActivity = { type: "message", attachments: [ @@ -349,7 +505,7 @@ export class TeamsBot extends TeamsActivityHandler { adaptiveCardActivity, { headers: { - Authorization: `Bearer ${botToken}`, + Authorization: `Bearer ${botAccessToken}`, "Content-Type": "application/json" } } @@ -364,18 +520,12 @@ export class TeamsBot extends TeamsActivityHandler { } // todo: filter out teams that the bot is not a member of - async getTeamsAndChannels(tenantId: string, internalAppId: string) { + async getTeamsAndChannels(accessToken: string, tenantId: string, internalAppId: string) { try { - const token = await getMicrosoftTeamsAccessToken({ - tenantId, - clientId: this.botAppId, - clientSecret: this.botAppPassword - }); - const teamsResponse = await axios .get<{ value: { displayName: string; id: string }[] }>(`https://graph.microsoft.com/v1.0/teams`, { headers: { - Authorization: `Bearer ${token}` + Authorization: `Bearer ${accessToken}` } }) .catch((error) => { @@ -393,7 +543,7 @@ export class TeamsBot extends TeamsActivityHandler { `https://graph.microsoft.com/v1.0/teams/${team.id}/installedApps?$expand=teamsAppDefinition`, { headers: { - Authorization: `Bearer ${token}` + Authorization: `Bearer ${accessToken}` } } ); @@ -412,7 +562,7 @@ export class TeamsBot extends TeamsActivityHandler { `https://graph.microsoft.com/v1.0/teams/${team.id}/channels`, { headers: { - Authorization: `Bearer ${token}` + Authorization: `Bearer ${accessToken}` } } ) diff --git a/backend/src/services/microsoft-teams/microsoft-teams-service.ts b/backend/src/services/microsoft-teams/microsoft-teams-service.ts index 25a6ffb01..7c741c396 100644 --- a/backend/src/services/microsoft-teams/microsoft-teams-service.ts +++ b/backend/src/services/microsoft-teams/microsoft-teams-service.ts @@ -18,7 +18,7 @@ import { KmsDataKey } from "../kms/kms-types"; import { TSuperAdminDALFactory } from "../super-admin/super-admin-dal"; import { TWorkflowIntegrationDALFactory } from "../workflow-integration/workflow-integration-dal"; import { WorkflowIntegration, WorkflowIntegrationStatus } from "../workflow-integration/workflow-integration-types"; -import { isBotInstalledInTenant, TeamsBot } from "./microsoft-teams-fns"; +import { getMicrosoftTeamsAccessToken, isBotInstalledInTenant, TeamsBot } from "./microsoft-teams-fns"; import { TMicrosoftTeamsIntegrationDALFactory } from "./microsoft-teams-integration-dal"; import { TCheckInstallationStatusDTO, @@ -56,6 +56,7 @@ type TMicrosoftTeamsServiceFactoryDep = { | "findById" | "findByIdWithWorkflowIntegrationDetails" | "findWithWorkflowIntegrationDetails" + | "update" >; permissionService: Pick; kmsService: Pick; @@ -131,16 +132,6 @@ export const microsoftTeamsServiceFactory = ({ actorAuthMethod, workflowIntegrationId }: TCheckInstallationStatusDTO) => { - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - actorOrgId, - actorAuthMethod, - actorOrgId - ); - - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); - const microsoftTeamsIntegration = await microsoftTeamsIntegrationDAL.findByIdWithWorkflowIntegrationDetails(workflowIntegrationId); @@ -150,6 +141,16 @@ export const microsoftTeamsServiceFactory = ({ }); } + const { permission } = await permissionService.getOrgPermission( + actor, + actorId, + microsoftTeamsIntegration.orgId, + actorAuthMethod, + actorOrgId + ); + + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); + const serverCfg = await serverCfgDAL.findById(ADMIN_CONFIG_DB_UUID); if (!serverCfg) { throw new BadRequestError({ @@ -175,7 +176,11 @@ export const microsoftTeamsServiceFactory = ({ tenantId: microsoftTeamsIntegration.tenantId, botAppId: decryptedAppId.toString(), botAppPassword: decryptedAppPassword.toString(), - botId: decryptedBotId.toString() + botId: decryptedBotId.toString(), + orgId: microsoftTeamsIntegration.orgId, + kmsService, + microsoftTeamsIntegrationDAL, + microsoftTeamsIntegrationId: microsoftTeamsIntegration.id }); if (!teamsBotInfo.installed) { @@ -258,12 +263,20 @@ export const microsoftTeamsServiceFactory = ({ const botAppPassword = decryptWithRoot(encryptedMicrosoftTeamsClientSecret); const botId = decryptWithRoot(encryptedMicrosoftTeamsBotId); - const teamsBotInfo = await isBotInstalledInTenant({ - tenantId: microsoftTeamsIntegration.tenantId, - botAppId: botAppId.toString(), - botAppPassword: botAppPassword.toString(), - botId: botId.toString() - }); + const teamsBotInfo = await isBotInstalledInTenant( + { + tenantId: microsoftTeamsIntegration.tenantId, + botAppId: botAppId.toString(), + botAppPassword: botAppPassword.toString(), + botId: botId.toString(), + orgId: workflowIntegration.orgId, + kmsService, + microsoftTeamsIntegrationDAL, + microsoftTeamsIntegrationId: microsoftTeamsIntegration.id + }, + tx + ); + if (teamsBotInfo.installed) { const { encryptor: orgDataKeyEncryptor } = await kmsService.createCipherPairWithDataKey({ orgId: workflowIntegration.orgId, @@ -451,16 +464,6 @@ export const microsoftTeamsServiceFactory = ({ }; const getTeams = async ({ actorId, actor, actorOrgId, actorAuthMethod, workflowIntegrationId }: TGetTeamsDTO) => { - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - actorOrgId, - actorAuthMethod, - actorOrgId - ); - - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Settings); - const microsoftTeamsIntegration = await microsoftTeamsIntegrationDAL.findByIdWithWorkflowIntegrationDetails(workflowIntegrationId); @@ -470,6 +473,16 @@ export const microsoftTeamsServiceFactory = ({ }); } + const { permission } = await permissionService.getOrgPermission( + actor, + actorId, + microsoftTeamsIntegration.orgId, + actorAuthMethod, + actorOrgId + ); + + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Settings); + if (!teamsBot || !adapter) { throw new BadRequestError({ message: "Unable to get teams and channels because the Microsoft Teams bot is uninitialized" @@ -498,11 +511,15 @@ export const microsoftTeamsServiceFactory = ({ const decryptedAppPassword = decryptWithRoot(serverCfg.encryptedMicrosoftTeamsClientSecret); const decryptedBotId = decryptWithRoot(serverCfg.encryptedMicrosoftTeamsBotId); - const { installed, internalId } = await isBotInstalledInTenant({ + const { installed, internalId, accessToken } = await isBotInstalledInTenant({ tenantId: microsoftTeamsIntegration.tenantId, botAppId: decryptedAppId.toString(), botAppPassword: decryptedAppPassword.toString(), - botId: decryptedBotId.toString() + botId: decryptedBotId.toString(), + orgId: actorOrgId, + kmsService, + microsoftTeamsIntegrationDAL, + microsoftTeamsIntegrationId: microsoftTeamsIntegration.id }); if (!installed) { @@ -511,7 +528,7 @@ export const microsoftTeamsServiceFactory = ({ }); } - const teams = await teamsBot.getTeamsAndChannels(microsoftTeamsIntegration.tenantId, internalId); + const teams = await teamsBot.getTeamsAndChannels(accessToken, microsoftTeamsIntegration.tenantId, internalId); return teams; }; @@ -580,15 +597,53 @@ export const microsoftTeamsServiceFactory = ({ }); }; - const sendNotification = async ({ tenantId, target, notification }: TSendNotificationDTO) => { + const sendNotification = async ({ + tenantId, + target, + notification, + orgId, + microsoftTeamsIntegrationId + }: TSendNotificationDTO) => { if (!teamsBot || !adapter) { throw new BadRequestError({ message: "Unable to send notification because the Microsoft Teams bot is uninitialized" }); } + const serverCfg = await serverCfgDAL.findById(ADMIN_CONFIG_DB_UUID); + if (!serverCfg) { + throw new BadRequestError({ + message: "Failed to get server configuration." + }); + } + + if ( + !serverCfg.encryptedMicrosoftTeamsAppId || + !serverCfg.encryptedMicrosoftTeamsClientSecret || + !serverCfg.encryptedMicrosoftTeamsBotId + ) { + throw new BadRequestError({ + message: "Microsoft Teams app ID, client secret, or bot ID is not set" + }); + } + + const decryptWithRoot = kmsService.decryptWithRootKey(); + const botAppId = decryptWithRoot(serverCfg.encryptedMicrosoftTeamsAppId); + const botAppPassword = decryptWithRoot(serverCfg.encryptedMicrosoftTeamsClientSecret); + + const botAccessToken = await getMicrosoftTeamsAccessToken({ + tenantId, + clientId: botAppId.toString(), + clientSecret: botAppPassword.toString(), + getBotFrameworkToken: true, + orgId, + kmsService, + microsoftTeamsIntegrationDAL, + microsoftTeamsIntegrationId + }); + for await (const channelId of target.channelIds) { - await teamsBot.sendMessageToChannel(tenantId, channelId, target.teamId, notification); + await teamsBot.sendMessageToChannel(botAccessToken, tenantId, channelId, target.teamId, notification); } }; diff --git a/backend/src/services/microsoft-teams/microsoft-teams-types.ts b/backend/src/services/microsoft-teams/microsoft-teams-types.ts index 3358f06f0..bf1f5db82 100644 --- a/backend/src/services/microsoft-teams/microsoft-teams-types.ts +++ b/backend/src/services/microsoft-teams/microsoft-teams-types.ts @@ -28,6 +28,8 @@ export type TDeleteMicrosoftTeamsIntegrationDTO = { export type TSendNotificationDTO = { tenantId: string; + microsoftTeamsIntegrationId: string; + orgId: string; target: { teamId: string; channelIds: string[]; diff --git a/frontend/src/pages/secret-manager/SettingsPage/components/WorkflowIntegrationSection/components/AddWorkflowIntegrationModal.tsx b/frontend/src/pages/secret-manager/SettingsPage/components/WorkflowIntegrationSection/components/AddWorkflowIntegrationModal.tsx index eccde5661..8601c1c02 100644 --- a/frontend/src/pages/secret-manager/SettingsPage/components/WorkflowIntegrationSection/components/AddWorkflowIntegrationModal.tsx +++ b/frontend/src/pages/secret-manager/SettingsPage/components/WorkflowIntegrationSection/components/AddWorkflowIntegrationModal.tsx @@ -86,7 +86,6 @@ export const AddWorkflowIntegrationModal = ({ isOpen, onToggle }: Props) => { return (
{ {isConfigured && (
-
+
Already Configured
@@ -126,7 +125,7 @@ export const AddWorkflowIntegrationModal = ({ isOpen, onToggle }: Props) => { {wizardStep === WizardSteps.PlatformInputs && selectedPlatform === WorkflowIntegrationPlatform.SLACK && ( { {wizardStep === WizardSteps.PlatformInputs && selectedPlatform === WorkflowIntegrationPlatform.MICROSOFT_TEAMS && ( )} + {integration === WorkflowIntegrationPlatform.MICROSOFT_TEAMS && ( + + )} ); diff --git a/frontend/src/pages/secret-manager/SettingsPage/components/WorkflowIntegrationSection/components/MicrosoftTeamsIntegrationForm.tsx b/frontend/src/pages/secret-manager/SettingsPage/components/WorkflowIntegrationSection/components/MicrosoftTeamsIntegrationForm.tsx index 3637745bc..166d76ca0 100644 --- a/frontend/src/pages/secret-manager/SettingsPage/components/WorkflowIntegrationSection/components/MicrosoftTeamsIntegrationForm.tsx +++ b/frontend/src/pages/secret-manager/SettingsPage/components/WorkflowIntegrationSection/components/MicrosoftTeamsIntegrationForm.tsx @@ -84,7 +84,7 @@ const formSchema = z } }); -type TSlackConfigForm = z.infer; +type TMicrosoftTeamsConfigForm = z.infer; type Props = { onClose: () => void; @@ -109,7 +109,7 @@ export const MicrosoftTeamsIntegrationForm = ({ onClose }: Props) => { handleSubmit, setValue, formState: { isDirty, isSubmitting } - } = useForm({ + } = useForm({ resolver: zodResolver(formSchema), defaultValues: { isAccessRequestNotificationEnabled: false, @@ -125,7 +125,7 @@ export const MicrosoftTeamsIntegrationForm = ({ onClose }: Props) => { } }); - const handleIntegrationSave = async (data: TSlackConfigForm) => { + const handleIntegrationSave = async (data: TMicrosoftTeamsConfigForm) => { try { if (!currentWorkspace) { return; @@ -374,7 +374,7 @@ export const MicrosoftTeamsIntegrationForm = ({ onClose }: Props) => { : [...(value || []), channel.channelId] ); }} - key={`secret-requests-slack-channel-${channel.channelId}`} + key={`secret-requests-microsoft-teams-channel-${channel.channelId}`} iconPos="right" icon={isChecked && } >