feat: finished org-level integration management flow

This commit is contained in:
Sheen Capadngan
2024-09-03 22:08:31 +08:00
parent 9120367562
commit a2b555dd81
23 changed files with 865 additions and 234 deletions
+7 -1
View File
@@ -61,7 +61,13 @@ export const registerV1Routes = async (server: FastifyZodProvider) => {
await server.register(registerUserActionRouter, { prefix: "/user-action" });
await server.register(registerSecretImportRouter, { prefix: "/secret-imports" });
await server.register(registerSecretFolderRouter, { prefix: "/folders" });
await server.register(registerSlackRouter, { prefix: "/slack" });
await server.register(
async (workflowIntegrationRouter) => {
await workflowIntegrationRouter.register(registerSlackRouter, { prefix: "/slack" });
},
{ prefix: "/workflow-integrations" }
);
await server.register(
async (projectRouter) => {
+126 -99
View File
@@ -6,7 +6,6 @@ import { getConfig } from "@app/lib/config/env";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { validateSlackChannelsField } from "@app/services/slack/slack-auth-validators";
export const registerSlackRouter = async (server: FastifyZodProvider) => {
const appCfg = getConfig();
@@ -24,7 +23,8 @@ export const registerSlackRouter = async (server: FastifyZodProvider) => {
}
],
querystring: z.object({
projectId: z.string()
slug: z.string(),
description: z.string().optional()
}),
response: {
200: z.string()
@@ -37,15 +37,18 @@ export const registerSlackRouter = async (server: FastifyZodProvider) => {
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.query.projectId
...req.query
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: req.query.projectId,
orgId: req.permission.orgId,
event: {
type: EventType.ATTEMPT_CREATE_SLACK_INTEGRATION,
metadata: {}
metadata: {
slug: req.query.slug,
description: req.query.description
}
}
});
@@ -65,104 +68,25 @@ export const registerSlackRouter = async (server: FastifyZodProvider) => {
bearerAuth: []
}
],
querystring: z.object({
projectId: z.string()
}),
response: {
200: SlackIntegrationsSchema.pick({
id: true,
teamName: true,
isAccessRequestNotificationEnabled: true,
accessRequestChannels: true,
isSecretRequestNotificationEnabled: true,
secretRequestChannels: true
})
slug: true,
description: true,
teamName: true
}).array()
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const slackIntegration = await server.services.slack.getSlackIntegrationByProjectId({
const slackIntegrations = await server.services.slack.getSlackIntegrationsByOrg({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.query.projectId
actorOrgId: req.permission.orgId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: req.query.projectId,
event: {
type: EventType.GET_SLACK_INTEGRATION,
metadata: {
id: slackIntegration?.id
}
}
});
return slackIntegration;
}
});
server.route({
method: "PATCH",
url: "/:slackIntegrationId",
config: {
rateLimit: writeLimit
},
schema: {
security: [
{
bearerAuth: []
}
],
params: z.object({
slackIntegrationId: z.string()
}),
body: z.object({
isAccessRequestNotificationEnabled: z.boolean().optional(),
accessRequestChannels: validateSlackChannelsField.optional(),
isSecretRequestNotificationEnabled: z.boolean().optional(),
secretRequestChannels: validateSlackChannelsField.optional()
}),
response: {
200: SlackIntegrationsSchema.pick({
id: true,
teamName: true,
isAccessRequestNotificationEnabled: true,
accessRequestChannels: true,
isSecretRequestNotificationEnabled: true,
secretRequestChannels: true
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const updatedSlackIntegration = await server.services.slack.updateSlackIntegration({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
id: req.params.slackIntegrationId,
...req.body
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: updatedSlackIntegration.projectId,
event: {
type: EventType.UPDATE_SLACK_INTEGRATION,
metadata: {
id: updatedSlackIntegration.id,
isAccessRequestNotificationEnabled: updatedSlackIntegration.isAccessRequestNotificationEnabled,
accessRequestChannels: updatedSlackIntegration.accessRequestChannels,
isSecretRequestNotificationEnabled: updatedSlackIntegration.isSecretRequestNotificationEnabled,
secretRequestChannels: updatedSlackIntegration.secretRequestChannels
}
}
});
return updatedSlackIntegration;
return slackIntegrations;
}
});
@@ -184,11 +108,9 @@ export const registerSlackRouter = async (server: FastifyZodProvider) => {
response: {
200: SlackIntegrationsSchema.pick({
id: true,
teamName: true,
isAccessRequestNotificationEnabled: true,
accessRequestChannels: true,
isSecretRequestNotificationEnabled: true,
secretRequestChannels: true
slug: true,
description: true,
teamName: true
})
}
},
@@ -204,7 +126,7 @@ export const registerSlackRouter = async (server: FastifyZodProvider) => {
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
projectId: deletedSlackIntegration.projectId,
orgId: deletedSlackIntegration.orgId,
event: {
type: EventType.DELETE_SLACK_INTEGRATION,
metadata: {
@@ -217,6 +139,111 @@ export const registerSlackRouter = async (server: FastifyZodProvider) => {
}
});
server.route({
method: "GET",
url: "/:slackIntegrationId",
config: {
rateLimit: readLimit
},
schema: {
security: [
{
bearerAuth: []
}
],
params: z.object({
slackIntegrationId: z.string()
}),
response: {
200: SlackIntegrationsSchema.pick({
id: true,
slug: true,
description: true,
teamName: true
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const slackIntegration = await server.services.slack.getSlackIntegrationById({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
id: req.params.slackIntegrationId
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: slackIntegration.orgId,
event: {
type: EventType.GET_SLACK_INTEGRATION,
metadata: {
id: slackIntegration.id
}
}
});
return slackIntegration;
}
});
server.route({
method: "PATCH",
url: "/:slackIntegrationId",
config: {
rateLimit: readLimit
},
schema: {
security: [
{
bearerAuth: []
}
],
params: z.object({
slackIntegrationId: z.string()
}),
body: z.object({
slug: z.string().optional(),
description: z.string().optional()
}),
response: {
200: SlackIntegrationsSchema.pick({
id: true,
slug: true,
description: true,
teamName: true
})
}
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const slackIntegration = await server.services.slack.updateSlackIntegration({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
id: req.params.slackIntegrationId,
...req.body
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: slackIntegration.orgId,
event: {
type: EventType.UPDATE_SLACK_INTEGRATION,
metadata: {
id: slackIntegration.id,
slug: slackIntegration.slug,
description: slackIntegration.description as string
}
}
});
return slackIntegration;
}
});
server.route({
method: "GET",
url: "/oauth_redirect",
@@ -232,10 +259,10 @@ export const registerSlackRouter = async (server: FastifyZodProvider) => {
},
successAsync: async (installation) => {
const metadata = JSON.parse(installation.metadata || "") as {
projectId: string;
orgId: string;
};
return res.redirect(`${appCfg.SITE_URL}/project/${metadata.projectId}/settings`);
return res.redirect(`${appCfg.SITE_URL}/org/${metadata.orgId}/settings`);
}
});
}