fix: requested changes

This commit is contained in:
Daniel Hougaard
2025-04-25 05:22:17 +04:00
parent f5fa57d6c5
commit 50679ba29d
16 changed files with 184 additions and 127 deletions
-1
View File
@@ -23,7 +23,6 @@ export const OrganizationsSchema = z.object({
defaultMembershipRole: z.string().default("member"), defaultMembershipRole: z.string().default("member"),
enforceMfa: z.boolean().default(false), enforceMfa: z.boolean().default(false),
selectedMfaMethod: z.string().nullable().optional(), selectedMfaMethod: z.string().nullable().optional(),
secretShareSendToAnyone: z.boolean().default(true).nullable().optional(),
allowSecretSharingOutsideOrganization: z.boolean().default(true).nullable().optional(), allowSecretSharingOutsideOrganization: z.boolean().default(true).nullable().optional(),
shouldUseNewPrivilegeSystem: z.boolean().default(true), shouldUseNewPrivilegeSystem: z.boolean().default(true),
privilegeUpgradeInitiatedByUsername: z.string().nullable().optional(), privilegeUpgradeInitiatedByUsername: z.string().nullable().optional(),
@@ -1,4 +1,4 @@
import { MicrosoftTeamsChannelsSchema } from "@app/services/microsoft-teams/microsoft-teams-fns"; import { validateMicrosoftTeamsChannelsSchema } from "@app/services/microsoft-teams/microsoft-teams-fns";
import { sendSlackNotification } from "@app/services/slack/slack-fns"; import { sendSlackNotification } from "@app/services/slack/slack-fns";
import { logger } from "../logger"; import { logger } from "../logger";
@@ -52,7 +52,9 @@ export const triggerWorkflowIntegrationNotification = async (dto: TTriggerWorkfl
if (microsoftTeamsConfig) { if (microsoftTeamsConfig) {
if (notification.type === TriggerFeature.ACCESS_REQUEST) { if (notification.type === TriggerFeature.ACCESS_REQUEST) {
if (microsoftTeamsConfig.isAccessRequestNotificationEnabled && microsoftTeamsConfig.accessRequestChannels) { if (microsoftTeamsConfig.isAccessRequestNotificationEnabled && microsoftTeamsConfig.accessRequestChannels) {
const { success, data } = MicrosoftTeamsChannelsSchema.safeParse(microsoftTeamsConfig.accessRequestChannels); const { success, data } = validateMicrosoftTeamsChannelsSchema.safeParse(
microsoftTeamsConfig.accessRequestChannels
);
if (success && data) { if (success && data) {
await microsoftTeamsService await microsoftTeamsService
@@ -68,7 +70,9 @@ export const triggerWorkflowIntegrationNotification = async (dto: TTriggerWorkfl
} }
} else if (notification.type === TriggerFeature.SECRET_APPROVAL) { } else if (notification.type === TriggerFeature.SECRET_APPROVAL) {
if (microsoftTeamsConfig.isSecretRequestNotificationEnabled && microsoftTeamsConfig.secretRequestChannels) { if (microsoftTeamsConfig.isSecretRequestNotificationEnabled && microsoftTeamsConfig.secretRequestChannels) {
const { success, data } = MicrosoftTeamsChannelsSchema.safeParse(microsoftTeamsConfig.secretRequestChannels); const { success, data } = validateMicrosoftTeamsChannelsSchema.safeParse(
microsoftTeamsConfig.secretRequestChannels
);
if (success && data) { if (success && data) {
await microsoftTeamsService await microsoftTeamsService
@@ -30,7 +30,7 @@ export const registerMicrosoftTeamsRouter = async (server: FastifyZodProvider) =
schema: { schema: {
body: z.object({ body: z.object({
tenantId: z.string(), tenantId: z.string(),
slug: z.string() slug: slugSchema({ max: 64 })
}), }),
response: { response: {
200: sanitizedMicrosoftTeamsIntegrationSchema 200: sanitizedMicrosoftTeamsIntegrationSchema
+47 -43
View File
@@ -20,8 +20,9 @@ import { re2Validator } from "@app/lib/zod";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { ActorType, AuthMode } from "@app/services/auth/auth-type"; import { ActorType, AuthMode } from "@app/services/auth/auth-type";
import { MicrosoftTeamsChannelsSchema } from "@app/services/microsoft-teams/microsoft-teams-fns"; import { validateMicrosoftTeamsChannelsSchema } from "@app/services/microsoft-teams/microsoft-teams-fns";
import { ProjectFilterType, SearchProjectSortBy } from "@app/services/project/project-types"; import { ProjectFilterType, SearchProjectSortBy } from "@app/services/project/project-types";
import { validateSlackChannelsField } from "@app/services/slack/slack-auth-validators";
import { WorkflowIntegration } from "@app/services/workflow-integration/workflow-integration-types"; import { WorkflowIntegration } from "@app/services/workflow-integration/workflow-integration-types";
import { integrationAuthPubSchema, SanitizedProjectSchema } from "../sanitizedSchemas"; import { integrationAuthPubSchema, SanitizedProjectSchema } from "../sanitizedSchemas";
@@ -666,19 +667,17 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
integration: req.params.integration integration: req.params.integration
}); });
if (config) { await server.services.auditLog.createAuditLog({
await server.services.auditLog.createAuditLog({ ...req.auditLogInfo,
...req.auditLogInfo, projectId: req.params.workspaceId,
projectId: req.params.workspaceId, event: {
event: { type: EventType.GET_PROJECT_WORKFLOW_INTEGRATION_CONFIG,
type: EventType.GET_PROJECT_WORKFLOW_INTEGRATION_CONFIG, metadata: {
metadata: { id: config.id,
id: config.id, integration: config.integration
integration: config.integration
}
} }
}); }
} });
return config; return config;
} }
@@ -686,7 +685,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
server.route({ server.route({
method: "DELETE", method: "DELETE",
url: "/:projectId/workflow-integrations/:integration/:integrationId", url: "/:projectId/workflow-integration/:integration/:integrationId",
config: { config: {
rateLimit: writeLimit rateLimit: writeLimit
}, },
@@ -695,7 +694,14 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
projectId: z.string().trim(), projectId: z.string().trim(),
integration: z.nativeEnum(WorkflowIntegration), integration: z.nativeEnum(WorkflowIntegration),
integrationId: z.string() integrationId: z.string()
}) }),
response: {
200: z.object({
integrationConfig: z.object({
id: z.string()
})
})
}
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
@@ -709,42 +715,41 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
integrationId: req.params.integrationId integrationId: req.params.integrationId
}); });
return deletedIntegration; return {
integrationConfig: deletedIntegration
};
} }
}); });
server.route({ server.route({
method: "PUT", method: "PUT",
url: "/:workspaceId/workflow-integration/:integration", url: "/:workspaceId/workflow-integration",
config: { config: {
rateLimit: readLimit rateLimit: readLimit
}, },
schema: { schema: {
params: z.object({ params: z.object({
workspaceId: z.string().trim(), workspaceId: z.string().trim()
integration: z.nativeEnum(WorkflowIntegration)
}),
body: z.object({
integrationId: z.string(),
isAccessRequestNotificationEnabled: z.boolean(),
accessRequestChannels: z.string().or(
z
.object({
teamId: z.string(),
channelIds: z.string().array()
})
.optional()
),
isSecretRequestNotificationEnabled: z.boolean(),
secretRequestChannels: z.string().or(
z
.object({
teamId: z.string(),
channelIds: z.string().array()
})
.optional()
)
}), }),
body: z.discriminatedUnion("integration", [
z.object({
integration: z.literal(WorkflowIntegration.SLACK),
integrationId: z.string(),
accessRequestChannels: validateSlackChannelsField,
secretRequestChannels: validateSlackChannelsField,
isAccessRequestNotificationEnabled: z.boolean(),
isSecretRequestNotificationEnabled: z.boolean()
}),
z.object({
integration: z.literal(WorkflowIntegration.MICROSOFT_TEAMS),
integrationId: z.string(),
accessRequestChannels: validateMicrosoftTeamsChannelsSchema,
secretRequestChannels: validateMicrosoftTeamsChannelsSchema,
isAccessRequestNotificationEnabled: z.boolean(),
isSecretRequestNotificationEnabled: z.boolean()
})
]),
response: { response: {
200: z.discriminatedUnion("integration", [ 200: z.discriminatedUnion("integration", [
ProjectSlackConfigsSchema.pick({ ProjectSlackConfigsSchema.pick({
@@ -767,8 +772,8 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
z.object({ z.object({
integration: z.literal(WorkflowIntegration.MICROSOFT_TEAMS), integration: z.literal(WorkflowIntegration.MICROSOFT_TEAMS),
integrationId: z.string(), integrationId: z.string(),
accessRequestChannels: MicrosoftTeamsChannelsSchema, accessRequestChannels: validateMicrosoftTeamsChannelsSchema,
secretRequestChannels: MicrosoftTeamsChannelsSchema secretRequestChannels: validateMicrosoftTeamsChannelsSchema
}) })
) )
]) ])
@@ -782,7 +787,6 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId, projectId: req.params.workspaceId,
integration: req.params.integration,
...req.body ...req.body
}); });
@@ -276,23 +276,27 @@ export class TeamsBot extends TeamsActivityHandler {
const botWasAdded = membersAdded.some((member) => member.id === context.activity.recipient.id); const botWasAdded = membersAdded.some((member) => member.id === context.activity.recipient.id);
if (botWasAdded && context.activity.conversation.tenantId) { if (botWasAdded && context.activity.conversation.tenantId) {
const microsoftTeamIntegration = await this.microsoftTeamsIntegrationDAL.findOne({ const microsoftTeamIntegration = await this.microsoftTeamsIntegrationDAL
tenantId: context.activity.conversation.tenantId .findOne({
}); tenantId: context.activity.conversation.tenantId
})
.catch(() => null);
await this.workflowIntegrationDAL if (microsoftTeamIntegration) {
.update( await this.workflowIntegrationDAL
{ .update(
id: microsoftTeamIntegration.id, {
status: WorkflowIntegrationStatus.PENDING id: microsoftTeamIntegration.id,
}, status: WorkflowIntegrationStatus.PENDING
{ },
status: WorkflowIntegrationStatus.INSTALLED {
} status: WorkflowIntegrationStatus.INSTALLED
) }
.catch((error) => { )
logger.error(error, "Microsoft Teams Workflow Integration: Failed to update workflow integration"); .catch((error) => {
}); logger.error(error, "Microsoft Teams Workflow Integration: Failed to update workflow integration");
});
}
// This is required in order for the bot to send proactive messages, which is required for the bot to pass the bot release validation step. // This is required in order for the bot to send proactive messages, which is required for the bot to pass the bot release validation step.
await context.sendActivity( await context.sendActivity(
@@ -308,47 +312,55 @@ export class TeamsBot extends TeamsActivityHandler {
} }
async sendMessageToChannel(tenantId: string, channelId: string, teamId: string, notification: TNotification) { async sendMessageToChannel(tenantId: string, channelId: string, teamId: string, notification: TNotification) {
const { adaptiveCard } = buildTeamsPayload(notification); try {
const { adaptiveCard } = buildTeamsPayload(notification);
const botToken = await getMicrosoftTeamsAccessToken({ const botToken = await getMicrosoftTeamsAccessToken({
tenantId, tenantId,
clientId: this.botAppId, clientId: this.botAppId,
clientSecret: this.botAppPassword, clientSecret: this.botAppPassword,
getBotFrameworkToken: true getBotFrameworkToken: true
}); });
const adaptiveCardActivity = { const adaptiveCardActivity = {
type: "message", type: "message",
attachments: [ attachments: [
{ {
contentType: "application/vnd.microsoft.card.adaptive", contentType: "application/vnd.microsoft.card.adaptive",
content: adaptiveCard content: adaptiveCard
} }
], ],
conversation: { conversation: {
id: channelId, id: channelId,
isGroup: true isGroup: true
},
channelData: {
channel: {
id: channelId
}, },
team: { channelData: {
id: teamId channel: {
id: channelId
},
team: {
id: teamId
}
} }
} };
};
await axios.post( await axios.post(
`https://smba.trafficmanager.net/amer/v3/conversations/${channelId}/activities`, `https://smba.trafficmanager.net/amer/v3/conversations/${channelId}/activities`,
adaptiveCardActivity, adaptiveCardActivity,
{ {
headers: { headers: {
Authorization: `Bearer ${botToken}`, Authorization: `Bearer ${botToken}`,
"Content-Type": "application/json" "Content-Type": "application/json"
}
} }
} );
); } catch (error) {
logger.error(
error,
`sendMessageToChannel: Microsoft Teams Workflow Integration: Failed to send message to channel [channelId=${channelId}] [teamId=${teamId}] [tenantId=${tenantId}]`
);
throw error;
}
} }
// todo: filter out teams that the bot is not a member of // todo: filter out teams that the bot is not a member of
@@ -429,7 +441,7 @@ export class TeamsBot extends TeamsActivityHandler {
} }
} }
export const MicrosoftTeamsChannelsSchema = z export const validateMicrosoftTeamsChannelsSchema = z
.object({ .object({
teamId: z.string(), teamId: z.string(),
channelIds: z.array(z.string()).min(1) channelIds: z.array(z.string()).min(1)
@@ -23,7 +23,7 @@ import { TMicrosoftTeamsIntegrationDALFactory } from "./microsoft-teams-integrat
import { import {
TCheckInstallationStatusDTO, TCheckInstallationStatusDTO,
TCreateMicrosoftTeamsIntegrationDTO, TCreateMicrosoftTeamsIntegrationDTO,
TDeleteMicrosoftTeamsIntegrationIntegrationDTO, TDeleteMicrosoftTeamsIntegrationDTO,
TGetMicrosoftTeamsIntegrationByIdDTO, TGetMicrosoftTeamsIntegrationByIdDTO,
TGetMicrosoftTeamsIntegrationByOrgDTO, TGetMicrosoftTeamsIntegrationByOrgDTO,
TGetTeamsDTO, TGetTeamsDTO,
@@ -424,7 +424,7 @@ export const microsoftTeamsServiceFactory = ({
actorOrgId, actorOrgId,
actorAuthMethod, actorAuthMethod,
id id
}: TDeleteMicrosoftTeamsIntegrationIntegrationDTO) => { }: TDeleteMicrosoftTeamsIntegrationDTO) => {
const microsoftTeamsIntegration = await microsoftTeamsIntegrationDAL.findByIdWithWorkflowIntegrationDetails(id); const microsoftTeamsIntegration = await microsoftTeamsIntegrationDAL.findByIdWithWorkflowIntegrationDetails(id);
if (!microsoftTeamsIntegration) { if (!microsoftTeamsIntegration) {
throw new NotFoundError({ throw new NotFoundError({
@@ -22,7 +22,7 @@ export type TGetTeamsDTO = Omit<TOrgPermission, "orgId"> & {
workflowIntegrationId: string; workflowIntegrationId: string;
}; };
export type TDeleteMicrosoftTeamsIntegrationIntegrationDTO = { export type TDeleteMicrosoftTeamsIntegrationDTO = {
id: string; id: string;
} & Omit<TOrgPermission, "orgId">; } & Omit<TOrgPermission, "orgId">;
@@ -43,7 +43,7 @@ import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
import { TIdentityProjectDALFactory } from "../identity-project/identity-project-dal"; import { TIdentityProjectDALFactory } from "../identity-project/identity-project-dal";
import { TIdentityProjectMembershipRoleDALFactory } from "../identity-project/identity-project-membership-role-dal"; import { TIdentityProjectMembershipRoleDALFactory } from "../identity-project/identity-project-membership-role-dal";
import { TKmsServiceFactory } from "../kms/kms-service"; import { TKmsServiceFactory } from "../kms/kms-service";
import { MicrosoftTeamsChannelsSchema } from "../microsoft-teams/microsoft-teams-fns"; import { validateMicrosoftTeamsChannelsSchema } from "../microsoft-teams/microsoft-teams-fns";
import { TMicrosoftTeamsIntegrationDALFactory } from "../microsoft-teams/microsoft-teams-integration-dal"; import { TMicrosoftTeamsIntegrationDALFactory } from "../microsoft-teams/microsoft-teams-integration-dal";
import { TProjectMicrosoftTeamsConfigDALFactory } from "../microsoft-teams/project-microsoft-teams-config-dal"; import { TProjectMicrosoftTeamsConfigDALFactory } from "../microsoft-teams/project-microsoft-teams-config-dal";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
@@ -1407,6 +1407,10 @@ export const projectServiceFactory = ({
integrationId: config.microsoftTeamsIntegrationId integrationId: config.microsoftTeamsIntegrationId
}; };
} }
throw new BadRequestError({
message: `Integration type '${integration as string}' not supported`
});
}; };
const updateProjectWorkflowIntegration = async ({ const updateProjectWorkflowIntegration = async ({
@@ -1526,9 +1530,6 @@ export const projectServiceFactory = ({
}); });
} }
const sanitizedAccessRequestChannels = MicrosoftTeamsChannelsSchema.parse(accessRequestChannels);
const sanitizedSecretRequestChannels = MicrosoftTeamsChannelsSchema.parse(secretRequestChannels);
const microsoftTeamsIntegration = const microsoftTeamsIntegration =
await microsoftTeamsIntegrationDAL.findByIdWithWorkflowIntegrationDetails(integrationId); await microsoftTeamsIntegrationDAL.findByIdWithWorkflowIntegrationDetails(integrationId);
@@ -1538,6 +1539,32 @@ export const projectServiceFactory = ({
}); });
} }
if (microsoftTeamsIntegration.orgId !== actorOrgId) {
throw new ForbiddenRequestError({
message: "Selected Microsoft Teams integration is not in the same organization"
});
}
const { permission } = await permissionService.getProjectPermission({
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId,
actionProjectType: ActionProjectType.Any
});
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings);
if (microsoftTeamsIntegration.orgId !== project.orgId) {
throw new ForbiddenRequestError({
message: "Selected Microsoft Teams integration is not in the same organization"
});
}
const sanitizedAccessRequestChannels = validateMicrosoftTeamsChannelsSchema.parse(accessRequestChannels);
const sanitizedSecretRequestChannels = validateMicrosoftTeamsChannelsSchema.parse(secretRequestChannels);
const updatedWorkflowIntegration = await projectMicrosoftTeamsConfigDAL.transaction(async (tx) => { const updatedWorkflowIntegration = await projectMicrosoftTeamsConfigDAL.transaction(async (tx) => {
const microsoftTeamsConfig = await projectMicrosoftTeamsConfigDAL.findOne( const microsoftTeamsConfig = await projectMicrosoftTeamsConfigDAL.findOne(
{ {
+19 -8
View File
@@ -164,14 +164,25 @@ export type TGetProjectWorkflowIntegrationConfig = TProjectPermission & {
integration: WorkflowIntegration; integration: WorkflowIntegration;
}; };
export type TUpdateProjectWorkflowIntegration = { export type TUpdateProjectWorkflowIntegration = (
integrationId: string; | {
integration: WorkflowIntegration; integrationId: string;
isAccessRequestNotificationEnabled: boolean; integration: WorkflowIntegration.SLACK;
accessRequestChannels?: string | { teamId: string; channelIds: string[] }; isAccessRequestNotificationEnabled: boolean;
isSecretRequestNotificationEnabled: boolean; isSecretRequestNotificationEnabled: boolean;
secretRequestChannels?: string | { teamId: string; channelIds: string[] }; accessRequestChannels?: string;
} & TProjectPermission; secretRequestChannels?: string;
}
| {
integrationId: string;
integration: WorkflowIntegration.MICROSOFT_TEAMS;
isAccessRequestNotificationEnabled: boolean;
isSecretRequestNotificationEnabled: boolean;
accessRequestChannels?: { teamId: string; channelIds: string[] };
secretRequestChannels?: { teamId: string; channelIds: string[] };
}
) &
TProjectPermission;
export type TDeleteProjectWorkflowIntegration = { export type TDeleteProjectWorkflowIntegration = {
integrationId: string; integrationId: string;
@@ -7,7 +7,7 @@ import { workflowIntegrationKeys } from "./queries";
import { import {
TCheckMicrosoftTeamsIntegrationInstallationStatusDTO, TCheckMicrosoftTeamsIntegrationInstallationStatusDTO,
TCreateMicrosoftTeamsIntegrationDTO, TCreateMicrosoftTeamsIntegrationDTO,
TDeleteMicrosoftTeamsIntegrationIntegrationDTO, TDeleteMicrosoftTeamsIntegrationDTO,
TDeleteProjectWorkflowIntegrationDTO, TDeleteProjectWorkflowIntegrationDTO,
TDeleteSlackIntegrationDTO, TDeleteSlackIntegrationDTO,
TUpdateMicrosoftTeamsIntegrationDTO, TUpdateMicrosoftTeamsIntegrationDTO,
@@ -93,7 +93,7 @@ export const useDeleteSlackIntegration = () => {
export const useDeleteMicrosoftTeamsIntegration = () => { export const useDeleteMicrosoftTeamsIntegration = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation<object, object, TDeleteMicrosoftTeamsIntegrationIntegrationDTO>({ return useMutation<object, object, TDeleteMicrosoftTeamsIntegrationDTO>({
mutationFn: async (dto) => { mutationFn: async (dto) => {
const { data } = await apiRequest.delete( const { data } = await apiRequest.delete(
`/api/v1/workflow-integrations/microsoft-teams/${dto.id}` `/api/v1/workflow-integrations/microsoft-teams/${dto.id}`
@@ -118,7 +118,7 @@ export const useUpdateProjectWorkflowIntegrationConfig = () => {
return useMutation({ return useMutation({
mutationFn: async (dto: TUpdateProjectWorkflowIntegrationConfigDTO) => { mutationFn: async (dto: TUpdateProjectWorkflowIntegrationConfigDTO) => {
const { data } = await apiRequest.put( const { data } = await apiRequest.put(
`/api/v1/workspace/${dto.workspaceId}/workflow-integration/${dto.integration}`, `/api/v1/workspace/${dto.workspaceId}/workflow-integration`,
dto dto
); );
@@ -138,7 +138,7 @@ export const useDeleteProjectWorkflowIntegration = () => {
return useMutation({ return useMutation({
mutationFn: async (dto: TDeleteProjectWorkflowIntegrationDTO) => { mutationFn: async (dto: TDeleteProjectWorkflowIntegrationDTO) => {
const { data } = await apiRequest.delete( const { data } = await apiRequest.delete(
`/api/v1/workspace/${dto.projectId}/workflow-integrations/${dto.integration}/${dto.integrationId}` `/api/v1/workspace/${dto.projectId}/workflow-integration/${dto.integration}/${dto.integrationId}`
); );
return data; return data;
@@ -70,7 +70,7 @@ export type TDeleteSlackIntegrationDTO = {
orgId: string; orgId: string;
}; };
export type TDeleteMicrosoftTeamsIntegrationIntegrationDTO = { export type TDeleteMicrosoftTeamsIntegrationDTO = {
id: string; id: string;
orgId: string; orgId: string;
}; };
@@ -141,7 +141,7 @@ export const MicrosoftTeamsIntegrationForm = ({ adminIntegrationsConfig }: Props
render={({ field, fieldState: { error } }) => ( render={({ field, fieldState: { error } }) => (
<FormControl <FormControl
label="Bot ID" label="Bot ID"
tooltipClassName="You can find the bot ID in your bot's manifest.json file as the `id` field." tooltipText="You can find the bot ID in your bot's manifest.json file as the `id` field."
className="w-96" className="w-96"
isError={Boolean(error)} isError={Boolean(error)}
errorText={error?.message} errorText={error?.message}
@@ -49,7 +49,7 @@ export const MicrosoftTeamsIntegrationForm = ({ id, onClose }: Props) => {
} }
}, [microsoftTeamsIntegration]); }, [microsoftTeamsIntegration]);
const handleSlackFormSubmit = async ({ const handleMicrosoftTeamsFormSubmit = async ({
slug, slug,
description, description,
tenantId tenantId
@@ -97,7 +97,7 @@ export const MicrosoftTeamsIntegrationForm = ({ id, onClose }: Props) => {
}; };
return ( return (
<form onSubmit={handleSubmit(handleSlackFormSubmit)} autoComplete="off"> <form onSubmit={handleSubmit(handleMicrosoftTeamsFormSubmit)} autoComplete="off">
<Controller <Controller
control={control} control={control}
name="slug" name="slug"
@@ -214,7 +214,7 @@ export const OrgWorkflowIntegrationTab = withPermission(
onClick={async (e) => { onClick={async (e) => {
e.stopPropagation(); e.stopPropagation();
await triggerSlackReinstall(workflowIntegration.integration); await triggerSlackReinstall(workflowIntegration.id);
}} }}
> >
Reinstall Reinstall
@@ -84,7 +84,7 @@ export const AddWorkflowIntegrationModal = ({ isOpen, onToggle }: Props) => {
(platform === WorkflowIntegrationPlatform.SLACK && slackConfigured); (platform === WorkflowIntegrationPlatform.SLACK && slackConfigured);
return ( return (
<div className="relative"> <div className="relative" key={platform}>
<div <div
key={platform} key={platform}
className={twMerge( className={twMerge(
@@ -78,7 +78,7 @@ export const MicrosoftTeamsConfigRow = ({ handlePopUpOpen }: Props) => {
<Spinner size="xs" /> <Spinner size="xs" />
) : ( ) : (
<Badge> <Badge>
{microsoftTeamsConfig.accessRequestChannels?.channelIds {(microsoftTeamsConfig.accessRequestChannels?.channelIds || [])
?.map((channel) => microsoftTeamsChannelIdToName[channel]) ?.map((channel) => microsoftTeamsChannelIdToName[channel])
.join(", ")} .join(", ")}
</Badge> </Badge>
@@ -89,7 +89,7 @@ export const MicrosoftTeamsConfigRow = ({ handlePopUpOpen }: Props) => {
<Spinner size="xs" /> <Spinner size="xs" />
) : ( ) : (
<Badge> <Badge>
{microsoftTeamsConfig.secretRequestChannels?.channelIds {(microsoftTeamsConfig.secretRequestChannels?.channelIds || [])
?.map((channel) => microsoftTeamsChannelIdToName[channel]) ?.map((channel) => microsoftTeamsChannelIdToName[channel])
.join(", ")} .join(", ")}
</Badge> </Badge>