mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-13 20:29:34 +00:00
misc: slack integration reinstall
This commit is contained in:
@@ -171,6 +171,7 @@ export enum EventType {
|
||||
UPDATE_CERTIFICATE_TEMPLATE_EST_CONFIG = "update-certificate-template-est-config",
|
||||
GET_CERTIFICATE_TEMPLATE_EST_CONFIG = "get-certificate-template-est-config",
|
||||
ATTEMPT_CREATE_SLACK_INTEGRATION = "attempt-create-slack-integration",
|
||||
ATTEMPT_REINSTALL_SLACK_INTEGRATION = "attempt-reinstall-slack-integration",
|
||||
GET_SLACK_INTEGRATION = "get-slack-integration",
|
||||
UPDATE_SLACK_INTEGRATION = "update-slack-integration",
|
||||
DELETE_SLACK_INTEGRATION = "delete-slack-integration",
|
||||
@@ -1460,6 +1461,13 @@ interface AttemptCreateSlackIntegration {
|
||||
};
|
||||
}
|
||||
|
||||
interface AttemptReinstallSlackIntegration {
|
||||
type: EventType.ATTEMPT_REINSTALL_SLACK_INTEGRATION;
|
||||
metadata: {
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface UpdateSlackIntegration {
|
||||
type: EventType.UPDATE_SLACK_INTEGRATION;
|
||||
metadata: {
|
||||
@@ -1634,6 +1642,7 @@ export type Event =
|
||||
| UpdateCertificateTemplateEstConfig
|
||||
| GetCertificateTemplateEstConfig
|
||||
| AttemptCreateSlackIntegration
|
||||
| AttemptReinstallSlackIntegration
|
||||
| UpdateSlackIntegration
|
||||
| DeleteSlackIntegration
|
||||
| GetSlackIntegration
|
||||
|
||||
@@ -56,6 +56,50 @@ export const registerSlackRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/reinstall",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
security: [
|
||||
{
|
||||
bearerAuth: []
|
||||
}
|
||||
],
|
||||
querystring: z.object({
|
||||
slackIntegrationId: z.string()
|
||||
}),
|
||||
response: {
|
||||
200: z.string()
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const url = await server.services.slack.getReinstallUrl({
|
||||
actor: req.permission.type,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
id: req.query.slackIntegrationId
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
event: {
|
||||
type: EventType.ATTEMPT_REINSTALL_SLACK_INTEGRATION,
|
||||
metadata: {
|
||||
id: req.query.slackIntegrationId
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return url;
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/",
|
||||
|
||||
@@ -12,9 +12,11 @@ import { TSlackIntegrationDALFactory } from "./slack-integration-dal";
|
||||
import {
|
||||
TCompleteSlackIntegrationDTO,
|
||||
TDeleteSlackIntegrationDTO,
|
||||
TGetReinstallUrlDTO,
|
||||
TGetSlackInstallUrlDTO,
|
||||
TGetSlackIntegrationByIdDTO,
|
||||
TGetSlackIntegrationByOrgDTO,
|
||||
TReinstallSlackIntegrationDTO,
|
||||
TUpdateSlackIntegrationDTO
|
||||
} from "./slack-types";
|
||||
|
||||
@@ -66,6 +68,38 @@ export const slackServiceFactory = ({
|
||||
});
|
||||
};
|
||||
|
||||
const reinstallSlackIntegration = async ({
|
||||
id,
|
||||
teamId,
|
||||
teamName,
|
||||
slackUserId,
|
||||
slackAppId,
|
||||
botAccessToken,
|
||||
slackBotId,
|
||||
slackBotUserId
|
||||
}: TReinstallSlackIntegrationDTO) => {
|
||||
const slackIntegration = await slackIntegrationDAL.findById(id);
|
||||
|
||||
const { encryptor: orgDataKeyEncryptor } = await kmsService.createCipherPairWithDataKey({
|
||||
orgId: slackIntegration.orgId,
|
||||
type: KmsDataKey.Organization
|
||||
});
|
||||
|
||||
const { cipherTextBlob: encryptedBotAccessToken } = orgDataKeyEncryptor({
|
||||
plainText: Buffer.from(botAccessToken, "utf8")
|
||||
});
|
||||
|
||||
await slackIntegrationDAL.updateById(id, {
|
||||
teamId,
|
||||
teamName,
|
||||
slackUserId,
|
||||
slackAppId,
|
||||
slackBotId,
|
||||
slackBotUserId,
|
||||
encryptedBotAccessToken
|
||||
});
|
||||
};
|
||||
|
||||
const getSlackInstaller = async () => {
|
||||
const appCfg = getConfig();
|
||||
|
||||
@@ -89,11 +123,25 @@ export const slackServiceFactory = ({
|
||||
}
|
||||
|
||||
const metadata = JSON.parse(installation.metadata || "") as {
|
||||
id?: string;
|
||||
orgId: string;
|
||||
slug: string;
|
||||
description?: string;
|
||||
};
|
||||
|
||||
if (metadata.id) {
|
||||
return reinstallSlackIntegration({
|
||||
id: metadata.id,
|
||||
teamId: installation.team?.id || "",
|
||||
teamName: installation.team?.name || "",
|
||||
slackUserId: installation.user.id,
|
||||
slackAppId: installation.appId || "",
|
||||
botAccessToken: installation.bot?.token || "",
|
||||
slackBotId: installation.bot?.id || "",
|
||||
slackBotUserId: installation.bot?.userId || ""
|
||||
});
|
||||
}
|
||||
|
||||
return completeSlackIntegration({
|
||||
orgId: metadata.orgId,
|
||||
slug: metadata.slug,
|
||||
@@ -154,6 +202,39 @@ export const slackServiceFactory = ({
|
||||
return url;
|
||||
};
|
||||
|
||||
const getReinstallUrl = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TGetReinstallUrlDTO) => {
|
||||
const appCfg = getConfig();
|
||||
const slackIntegration = await slackIntegrationDAL.findById(id);
|
||||
|
||||
if (!slackIntegration) {
|
||||
throw new NotFoundError({
|
||||
message: "Slack integration not found"
|
||||
});
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
slackIntegration.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Settings);
|
||||
|
||||
const installer = await getSlackInstaller();
|
||||
const url = await installer.generateInstallUrl({
|
||||
scopes: ["chat:write.public", "chat:write", "channels:read", "groups:read", "im:read", "mpim:read"],
|
||||
metadata: JSON.stringify({
|
||||
id,
|
||||
orgId: slackIntegration.orgId
|
||||
}),
|
||||
redirectUri: `${appCfg.SITE_URL}/api/v1/workflow-integrations/slack/oauth_redirect`
|
||||
});
|
||||
|
||||
return url;
|
||||
};
|
||||
|
||||
const getSlackIntegrationsByOrg = async ({
|
||||
actorId,
|
||||
actor,
|
||||
@@ -265,6 +346,7 @@ export const slackServiceFactory = ({
|
||||
|
||||
return {
|
||||
getInstallUrl,
|
||||
getReinstallUrl,
|
||||
getSlackIntegrationsByOrg,
|
||||
getSlackIntegrationById,
|
||||
completeSlackIntegration,
|
||||
|
||||
@@ -5,6 +5,10 @@ export type TGetSlackInstallUrlDTO = {
|
||||
description?: string;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TGetReinstallUrlDTO = {
|
||||
id: string;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TGetSlackIntegrationByOrgDTO = Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TGetSlackIntegrationByIdDTO = { id: string } & Omit<TOrgPermission, "orgId">;
|
||||
@@ -31,6 +35,17 @@ export type TCompleteSlackIntegrationDTO = {
|
||||
slackBotUserId: string;
|
||||
};
|
||||
|
||||
export type TReinstallSlackIntegrationDTO = {
|
||||
id: string;
|
||||
teamId: string;
|
||||
teamName: string;
|
||||
slackUserId: string;
|
||||
slackAppId: string;
|
||||
botAccessToken: string;
|
||||
slackBotId: string;
|
||||
slackBotUserId: string;
|
||||
};
|
||||
|
||||
export enum SlackTriggerFeature {
|
||||
SECRET_APPROVAL = "secret-approval",
|
||||
ACCESS_REQUEST = "access-request"
|
||||
|
||||
Reference in New Issue
Block a user