Modify frontend to be compatible with full-loop for bot-based integrations

This commit is contained in:
Tuan Dang
2022-12-10 15:43:22 -05:00
parent 436f408fa8
commit c2eaea21f0
13 changed files with 413 additions and 158 deletions
@@ -1,11 +1,9 @@
import { Request, Response } from 'express';
import { readFileSync } from 'fs';
import * as Sentry from '@sentry/node';
import axios from 'axios';
import { Integration } from '../models';
import { decryptAsymmetric } from '../utils/crypto';
import { decryptSecrets } from '../helpers/secret';
import { PRIVATE_KEY } from '../config';
import { Integration, Bot, BotKey } from '../models';
import { EventService } from '../services';
import { eventPushSecrets } from '../events';
interface Key {
encryptedKey: string;
@@ -55,26 +53,40 @@ export const getIntegrations = async (req: Request, res: Response) => {
* @param res
* @returns
*/
export const modifyIntegration = async (req: Request, res: Response) => {
export const updateIntegration = async (req: Request, res: Response) => {
let integration;
try {
const { update } = req.body;
const { app, environment, isActive } = req.body;
integration = await Integration.findOneAndUpdate(
{
_id: req.integration._id
},
update,
{
app,
environment,
isActive
},
{
new: true
}
);
if (integration) {
// trigger event - push secrets
EventService.handleEvent({
event: eventPushSecrets({
workspaceId: integration.workspace.toString()
})
});
}
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
return res.status(400).send({
message: 'Failed to modify integration'
message: 'Failed to update integration'
});
}
@@ -84,7 +96,8 @@ export const modifyIntegration = async (req: Request, res: Response) => {
};
/**
* Delete integration with id [integrationId]
* Delete integration with id [integrationId] and deactivate bot if there are
* no integrations left
* @param req
* @param res
* @returns
@@ -97,6 +110,29 @@ export const deleteIntegration = async (req: Request, res: Response) => {
deletedIntegration = await Integration.findOneAndDelete({
_id: integrationId
});
if (!deletedIntegration) throw new Error('Failed to find integration');
const integrations = await Integration.find({
workspace: deletedIntegration.workspace
});
if (integrations.length === 0) {
// case: no integrations left, deactivate bot
const bot = await Bot.findOneAndUpdate({
workspace: deletedIntegration.workspace
}, {
isActive: false
}, {
new: true
});
if (bot) {
await BotKey.deleteOne({
bot: bot._id
});
}
}
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
+7 -8
View File
@@ -62,14 +62,6 @@ export const pushSecrets = async (req: Request, res: Response) => {
keys
});
// trigger event
EventService.handleEvent({
event: eventPushSecrets({
workspaceId,
environment,
secrets
})
});
if (postHogClient) {
postHogClient.capture({
@@ -84,6 +76,13 @@ export const pushSecrets = async (req: Request, res: Response) => {
});
}
// trigger event - push secrets
EventService.handleEvent({
event: eventPushSecrets({
workspaceId
})
});
} catch (err) {
Sentry.setUser({ email: req.user.email });
Sentry.captureException(err);
+1 -8
View File
@@ -16,25 +16,18 @@ interface PushSecret {
* Return event for pushing secrets
* @param {Object} obj
* @param {String} obj.workspaceId - id of workspace to push secrets to
* @param {String} obj.environment - environment for secrets
* @param {PushSecret[]} obj.secrets - secrets to push
* @returns
*/
const eventPushSecrets = ({
workspaceId,
environment,
secrets
}: {
workspaceId: string;
environment: string;
secrets: PushSecret[];
}) => {
return ({
name: EVENT_PUSH_SECRETS,
workspaceId,
payload: {
environment,
secrets
}
});
}
+11 -13
View File
@@ -73,20 +73,18 @@ const handleOAuthExchangeHelper = async ({
accessExpiresAt: res.accessExpiresAt
});
// initializes an integration after exchange
await Integration.findOneAndUpdate(
{ workspace: workspaceId, integration },
{
workspace: workspaceId,
environment: ENV_DEV,
isActive: false,
app: null,
integration,
integrationAuth: integrationAuth._id
},
{ upsert: true, new: true }
);
// initialize new integration after exchange
await new Integration({
workspace: workspaceId,
environment: ENV_DEV,
isActive: false,
app: null,
integration,
integrationAuth: integrationAuth._id
}).save();
} catch (err) {
console.error('in', err);
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error('Failed to handle OAuth2 code-token exchange')
+1 -2
View File
@@ -37,8 +37,7 @@ const integrationSchema = new Schema<IIntegration>(
app: {
// name of app in provider
type: String,
default: null,
required: true
default: null
},
integration: {
type: String,
+6 -4
View File
@@ -18,10 +18,12 @@ router.patch(
acceptedRoles: [ADMIN, MEMBER],
acceptedStatuses: [GRANTED]
}),
param('integrationId'),
body('update'),
param('integrationId').exists().trim(),
body('app').exists().trim(),
body('environment').exists().trim(),
body('isActive').exists().isBoolean(),
validateRequest,
integrationController.modifyIntegration
integrationController.updateIntegration
);
router.delete(
@@ -31,7 +33,7 @@ router.delete(
acceptedRoles: [ADMIN, MEMBER],
acceptedStatuses: [GRANTED]
}),
param('integrationId'),
param('integrationId').exists().trim(),
validateRequest,
integrationController.deleteIntegration
);