mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 14:27:23 +00:00
Merge pull request #2358 from Infisical/feat/native-slack-integration
feat: native slack integration
This commit is contained in:
@@ -1,2 +1,7 @@
|
||||
export { useAdminDeleteUser, useCreateAdminUser, useUpdateServerConfig } from "./mutation";
|
||||
export { useAdminGetUsers, useGetServerConfig } from "./queries";
|
||||
export {
|
||||
useAdminDeleteUser,
|
||||
useCreateAdminUser,
|
||||
useUpdateAdminSlackConfig,
|
||||
useUpdateServerConfig
|
||||
} from "./mutation";
|
||||
export { useAdminGetUsers, useGetAdminSlackConfig, useGetServerConfig } from "./queries";
|
||||
|
||||
@@ -5,7 +5,12 @@ import { apiRequest } from "@app/config/request";
|
||||
import { organizationKeys } from "../organization/queries";
|
||||
import { User } from "../users/types";
|
||||
import { adminQueryKeys, adminStandaloneKeys } from "./queries";
|
||||
import { TCreateAdminUserDTO, TServerConfig } from "./types";
|
||||
import {
|
||||
AdminSlackConfig,
|
||||
TCreateAdminUserDTO,
|
||||
TServerConfig,
|
||||
TUpdateAdminSlackConfigDTO
|
||||
} from "./types";
|
||||
|
||||
export const useCreateAdminUser = () => {
|
||||
const queryClient = useQueryClient();
|
||||
@@ -28,7 +33,11 @@ export const useCreateAdminUser = () => {
|
||||
export const useUpdateServerConfig = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<TServerConfig, {}, Partial<TServerConfig>>({
|
||||
return useMutation<
|
||||
TServerConfig,
|
||||
{},
|
||||
Partial<TServerConfig & { slackClientId: string; slackClientSecret: string }>
|
||||
>({
|
||||
mutationFn: async (opt) => {
|
||||
const { data } = await apiRequest.patch<{ config: TServerConfig }>(
|
||||
"/api/v1/admin/config",
|
||||
@@ -59,3 +68,20 @@ export const useAdminDeleteUser = () => {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateAdminSlackConfig = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation<AdminSlackConfig, {}, TUpdateAdminSlackConfigDTO>({
|
||||
mutationFn: async (dto) => {
|
||||
const { data } = await apiRequest.put<AdminSlackConfig>(
|
||||
"/api/v1/admin/integrations/slack/config",
|
||||
dto
|
||||
);
|
||||
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(adminQueryKeys.getAdminSlackConfig());
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useInfiniteQuery, useQuery, UseQueryOptions } from "@tanstack/react-que
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { User } from "../types";
|
||||
import { AdminGetUsersFilters, TServerConfig } from "./types";
|
||||
import { AdminGetUsersFilters, AdminSlackConfig, TServerConfig } from "./types";
|
||||
|
||||
export const adminStandaloneKeys = {
|
||||
getUsers: "get-users"
|
||||
@@ -11,7 +11,8 @@ export const adminStandaloneKeys = {
|
||||
|
||||
export const adminQueryKeys = {
|
||||
serverConfig: () => ["server-config"] as const,
|
||||
getUsers: (filters: AdminGetUsersFilters) => [adminStandaloneKeys.getUsers, { filters }] as const
|
||||
getUsers: (filters: AdminGetUsersFilters) => [adminStandaloneKeys.getUsers, { filters }] as const,
|
||||
getAdminSlackConfig: () => ["admin-slack-config"] as const
|
||||
};
|
||||
|
||||
const fetchServerConfig = async () => {
|
||||
@@ -59,3 +60,15 @@ export const useAdminGetUsers = (filters: AdminGetUsersFilters) => {
|
||||
lastPage.length !== 0 ? pages.length * filters.limit : undefined
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetAdminSlackConfig = () =>
|
||||
useQuery({
|
||||
queryKey: adminQueryKeys.getAdminSlackConfig(),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<AdminSlackConfig>(
|
||||
"/api/v1/admin/integrations/slack/config"
|
||||
);
|
||||
|
||||
return data;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -38,7 +38,17 @@ export type TCreateAdminUserDTO = {
|
||||
salt: string;
|
||||
};
|
||||
|
||||
export type TUpdateAdminSlackConfigDTO = {
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
};
|
||||
|
||||
export type AdminGetUsersFilters = {
|
||||
limit: number;
|
||||
searchTerm: string;
|
||||
};
|
||||
|
||||
export type AdminSlackConfig = {
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
};
|
||||
|
||||
@@ -77,7 +77,9 @@ export const eventToNameMap: { [K in EventType]: string } = {
|
||||
[EventType.CREATE_CERTIFICATE_TEMPLATE_EST_CONFIG]:
|
||||
"Create certificate template EST configuration",
|
||||
[EventType.UPDATE_CERTIFICATE_TEMPLATE_EST_CONFIG]:
|
||||
"Update certificate template EST configuration"
|
||||
"Update certificate template EST configuration",
|
||||
[EventType.UPDATE_PROJECT_SLACK_CONFIG]: "Update project slack configuration",
|
||||
[EventType.GET_PROJECT_SLACK_CONFIG]: "Get project slack configuration"
|
||||
};
|
||||
|
||||
export const userAgentTTypeoNameMap: { [K in UserAgentType]: string } = {
|
||||
|
||||
@@ -89,5 +89,7 @@ export enum EventType {
|
||||
GET_CERTIFICATE_TEMPLATE = "get-certificate-template",
|
||||
CREATE_CERTIFICATE_TEMPLATE_EST_CONFIG = "create-certificate-template-est-config",
|
||||
UPDATE_CERTIFICATE_TEMPLATE_EST_CONFIG = "update-certificate-template-est-config",
|
||||
GET_CERTIFICATE_TEMPLATE_EST_CONFIG = "get-certificate-template-est-config"
|
||||
GET_CERTIFICATE_TEMPLATE_EST_CONFIG = "get-certificate-template-est-config",
|
||||
UPDATE_PROJECT_SLACK_CONFIG = "update-project-slack-config",
|
||||
GET_PROJECT_SLACK_CONFIG = "get-project-slack-config"
|
||||
}
|
||||
|
||||
@@ -742,6 +742,25 @@ interface GetCertificateTemplateEstConfig {
|
||||
};
|
||||
}
|
||||
|
||||
interface UpdateProjectSlackConfig {
|
||||
type: EventType.UPDATE_PROJECT_SLACK_CONFIG;
|
||||
metadata: {
|
||||
id: string;
|
||||
slackIntegrationId: string;
|
||||
isAccessRequestNotificationEnabled: boolean;
|
||||
accessRequestChannels: string;
|
||||
isSecretRequestNotificationEnabled: boolean;
|
||||
secretRequestChannels: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface GetProjectSlackConfig {
|
||||
type: EventType.GET_PROJECT_SLACK_CONFIG;
|
||||
metadata: {
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type Event =
|
||||
| GetSecretsEvent
|
||||
| GetSecretEvent
|
||||
@@ -817,7 +836,9 @@ export type Event =
|
||||
| DeleteCertificateTemplate
|
||||
| UpdateCertificateTemplateEstConfig
|
||||
| CreateCertificateTemplateEstConfig
|
||||
| GetCertificateTemplateEstConfig;
|
||||
| GetCertificateTemplateEstConfig
|
||||
| UpdateProjectSlackConfig
|
||||
| GetProjectSlackConfig;
|
||||
|
||||
export type AuditLog = {
|
||||
id: string;
|
||||
|
||||
@@ -44,4 +44,5 @@ export * from "./tags";
|
||||
export * from "./trustedIps";
|
||||
export * from "./users";
|
||||
export * from "./webhooks";
|
||||
export * from "./workflowIntegrations";
|
||||
export * from "./workspace";
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
export {
|
||||
useDeleteSlackIntegration,
|
||||
useUpdateProjectSlackConfig,
|
||||
useUpdateSlackIntegration
|
||||
} from "./mutation";
|
||||
export {
|
||||
fetchSlackInstallUrl,
|
||||
fetchSlackReinstallUrl,
|
||||
useGetSlackIntegrationById,
|
||||
useGetSlackIntegrationChannels,
|
||||
useGetSlackIntegrations,
|
||||
useGetWorkflowIntegrations
|
||||
} from "./queries";
|
||||
@@ -0,0 +1,60 @@
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { workspaceKeys } from "../workspace/queries";
|
||||
import { workflowIntegrationKeys } from "./queries";
|
||||
import {
|
||||
TDeleteSlackIntegrationDTO,
|
||||
TUpdateProjectSlackConfigDTO,
|
||||
TUpdateSlackIntegrationDTO
|
||||
} from "./types";
|
||||
|
||||
export const useUpdateSlackIntegration = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<{}, {}, TUpdateSlackIntegrationDTO>({
|
||||
mutationFn: async (dto) => {
|
||||
const { data } = await apiRequest.patch(`/api/v1/workflow-integrations/slack/${dto.id}`, dto);
|
||||
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { orgId, id }) => {
|
||||
queryClient.invalidateQueries(workflowIntegrationKeys.getSlackIntegration(id));
|
||||
queryClient.invalidateQueries(workflowIntegrationKeys.getSlackIntegrations(orgId));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteSlackIntegration = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<{}, {}, TDeleteSlackIntegrationDTO>({
|
||||
mutationFn: async (dto) => {
|
||||
const { data } = await apiRequest.delete(`/api/v1/workflow-integrations/slack/${dto.id}`);
|
||||
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { orgId, id }) => {
|
||||
queryClient.invalidateQueries(workflowIntegrationKeys.getSlackIntegration(id));
|
||||
queryClient.invalidateQueries(workflowIntegrationKeys.getIntegrations(orgId));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateProjectSlackConfig = () => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async (dto: TUpdateProjectSlackConfigDTO) => {
|
||||
const { data } = await apiRequest.put(
|
||||
`/api/v1/workspace/${dto.workspaceId}/slack-config`,
|
||||
dto
|
||||
);
|
||||
|
||||
return data;
|
||||
},
|
||||
onSuccess: (_, { workspaceId }) => {
|
||||
queryClient.invalidateQueries(workspaceKeys.getWorkspaceSlackConfig(workspaceId));
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { SlackIntegration, SlackIntegrationChannel, WorkflowIntegration } from "./types";
|
||||
|
||||
export const workflowIntegrationKeys = {
|
||||
getIntegrations: (orgId?: string) => [{ orgId }, "workflow-integrations"],
|
||||
getSlackIntegrations: (orgId?: string) => [{ orgId }, "slack-workflow-integrations"],
|
||||
getSlackIntegration: (id?: string) => [{ id }, "slack-workflow-integration"],
|
||||
getSlackIntegrationChannels: (id?: string) => [{ id }, "slack-workflow-integration-channels"]
|
||||
};
|
||||
|
||||
export const fetchSlackInstallUrl = async ({
|
||||
slug,
|
||||
description
|
||||
}: {
|
||||
slug: string;
|
||||
description?: string;
|
||||
}) => {
|
||||
const { data } = await apiRequest.get<string>("/api/v1/workflow-integrations/slack/install", {
|
||||
params: {
|
||||
slug,
|
||||
description
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const fetchSlackReinstallUrl = async ({ id }: { id: string }) => {
|
||||
const { data } = await apiRequest.get<string>("/api/v1/workflow-integrations/slack/reinstall", {
|
||||
params: {
|
||||
id
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const fetchSlackIntegrations = async () => {
|
||||
const { data } = await apiRequest.get<SlackIntegration[]>("/api/v1/workflow-integrations/slack");
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const fetchSlackIntegrationById = async (id?: string) => {
|
||||
const { data } = await apiRequest.get<SlackIntegration>(
|
||||
`/api/v1/workflow-integrations/slack/${id}`
|
||||
);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const fetchSlackIntegrationChannels = async (id?: string) => {
|
||||
const { data } = await apiRequest.get<SlackIntegrationChannel[]>(
|
||||
`/api/v1/workflow-integrations/slack/${id}/channels`
|
||||
);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const fetchWorkflowIntegrations = async () => {
|
||||
const { data } = await apiRequest.get<WorkflowIntegration[]>("/api/v1/workflow-integrations");
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const useGetSlackIntegrations = (orgId?: string) =>
|
||||
useQuery({
|
||||
queryKey: workflowIntegrationKeys.getSlackIntegrations(orgId),
|
||||
queryFn: () => fetchSlackIntegrations(),
|
||||
enabled: Boolean(orgId)
|
||||
});
|
||||
|
||||
export const useGetSlackIntegrationById = (id?: string) =>
|
||||
useQuery({
|
||||
queryKey: workflowIntegrationKeys.getSlackIntegration(id),
|
||||
queryFn: () => fetchSlackIntegrationById(id),
|
||||
enabled: Boolean(id)
|
||||
});
|
||||
|
||||
export const useGetSlackIntegrationChannels = (id?: string) =>
|
||||
useQuery({
|
||||
queryKey: workflowIntegrationKeys.getSlackIntegrationChannels(id),
|
||||
queryFn: () => fetchSlackIntegrationChannels(id),
|
||||
enabled: Boolean(id)
|
||||
});
|
||||
|
||||
export const useGetWorkflowIntegrations = (id?: string) =>
|
||||
useQuery({
|
||||
queryKey: workflowIntegrationKeys.getIntegrations(id),
|
||||
queryFn: () => fetchWorkflowIntegrations(),
|
||||
enabled: Boolean(id)
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
export enum WorkflowIntegrationPlatform {
|
||||
SLACK = "slack"
|
||||
}
|
||||
|
||||
export type WorkflowIntegration = {
|
||||
id: string;
|
||||
slug: string;
|
||||
description: string;
|
||||
integration: WorkflowIntegrationPlatform;
|
||||
};
|
||||
|
||||
export type SlackIntegration = {
|
||||
id: string;
|
||||
slug: string;
|
||||
description: string;
|
||||
teamName: string;
|
||||
};
|
||||
|
||||
export type SlackIntegrationChannel = {
|
||||
id: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type TUpdateSlackIntegrationDTO = {
|
||||
id: string;
|
||||
orgId: string;
|
||||
slug?: string;
|
||||
description?: string;
|
||||
};
|
||||
|
||||
export type TDeleteSlackIntegrationDTO = {
|
||||
id: string;
|
||||
orgId: string;
|
||||
};
|
||||
|
||||
export type ProjectSlackConfig = {
|
||||
id: string;
|
||||
slackIntegrationId: string;
|
||||
isAccessRequestNotificationEnabled: boolean;
|
||||
accessRequestChannels: string;
|
||||
isSecretRequestNotificationEnabled: boolean;
|
||||
secretRequestChannels: string;
|
||||
};
|
||||
|
||||
export type TUpdateProjectSlackConfigDTO = {
|
||||
workspaceId: string;
|
||||
slackIntegrationId: string;
|
||||
isAccessRequestNotificationEnabled: boolean;
|
||||
accessRequestChannels: string;
|
||||
isSecretRequestNotificationEnabled: boolean;
|
||||
secretRequestChannels: string;
|
||||
};
|
||||
@@ -22,6 +22,7 @@ export {
|
||||
useGetWorkspaceIndexStatus,
|
||||
useGetWorkspaceIntegrations,
|
||||
useGetWorkspaceSecrets,
|
||||
useGetWorkspaceSlackConfig,
|
||||
useGetWorkspaceUsers,
|
||||
useListWorkspaceCas,
|
||||
useListWorkspaceCertificates,
|
||||
|
||||
@@ -16,6 +16,7 @@ import { TPkiCollection } from "../pkiCollections/types";
|
||||
import { EncryptedSecret } from "../secrets/types";
|
||||
import { userKeys } from "../users/queries";
|
||||
import { TWorkspaceUser } from "../users/types";
|
||||
import { ProjectSlackConfig } from "../workflowIntegrations/types";
|
||||
import {
|
||||
CreateEnvironmentDTO,
|
||||
CreateWorkspaceDTO,
|
||||
@@ -71,7 +72,9 @@ export const workspaceKeys = {
|
||||
getWorkspacePkiCollections: (workspaceId: string) =>
|
||||
[{ workspaceId }, "workspace-pki-collections"] as const,
|
||||
getWorkspaceCertificateTemplates: (workspaceId: string) =>
|
||||
[{ workspaceId }, "workspace-certificate-templates"] as const
|
||||
[{ workspaceId }, "workspace-certificate-templates"] as const,
|
||||
getWorkspaceSlackConfig: (workspaceId: string) =>
|
||||
[{ workspaceId }, "workspace-slack-config"] as const
|
||||
};
|
||||
|
||||
const fetchWorkspaceById = async (workspaceId: string) => {
|
||||
@@ -667,3 +670,17 @@ export const useListWorkspaceCertificateTemplates = ({ workspaceId }: { workspac
|
||||
enabled: Boolean(workspaceId)
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetWorkspaceSlackConfig = ({ workspaceId }: { workspaceId: string }) => {
|
||||
return useQuery({
|
||||
queryKey: workspaceKeys.getWorkspaceSlackConfig(workspaceId),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<ProjectSlackConfig>(
|
||||
`/api/v1/workspace/${workspaceId}/slack-config`
|
||||
);
|
||||
|
||||
return data;
|
||||
},
|
||||
enabled: Boolean(workspaceId)
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user