mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 13:27:46 +00:00
Begin refactoring all integrations to separate integration pages by step
This commit is contained in:
Generated
+18
-82
@@ -10,13 +10,13 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@godaddy/terminus": "^4.11.2",
|
"@godaddy/terminus": "^4.11.2",
|
||||||
"@sentry/node": "^7.21.1",
|
|
||||||
"@octokit/rest": "^19.0.5",
|
"@octokit/rest": "^19.0.5",
|
||||||
"@sentry/tracing": "^7.21.1",
|
"@sentry/node": "^7.14.0",
|
||||||
|
"@sentry/tracing": "^7.19.0",
|
||||||
"@types/crypto-js": "^4.1.1",
|
"@types/crypto-js": "^4.1.1",
|
||||||
"axios": "^1.2.0",
|
|
||||||
"@types/libsodium-wrappers": "^0.7.10",
|
"@types/libsodium-wrappers": "^0.7.10",
|
||||||
"await-to-js": "^3.0.0",
|
"await-to-js": "^3.0.0",
|
||||||
|
"axios": "^1.1.3",
|
||||||
"bcrypt": "^5.1.0",
|
"bcrypt": "^5.1.0",
|
||||||
"bigint-conversion": "^2.2.2",
|
"bigint-conversion": "^2.2.2",
|
||||||
"builder-pattern": "^2.2.0",
|
"builder-pattern": "^2.2.0",
|
||||||
@@ -32,9 +32,9 @@
|
|||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"jsrp": "^0.2.4",
|
"jsrp": "^0.2.4",
|
||||||
"mongoose": "^6.7.3",
|
|
||||||
"libsodium-wrappers": "^0.7.10",
|
"libsodium-wrappers": "^0.7.10",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"mongoose": "^6.7.2",
|
||||||
"nodemailer": "^6.8.0",
|
"nodemailer": "^6.8.0",
|
||||||
"posthog-node": "^2.2.2",
|
"posthog-node": "^2.2.2",
|
||||||
"query-string": "^7.1.3",
|
"query-string": "^7.1.3",
|
||||||
@@ -2838,19 +2838,6 @@
|
|||||||
"@maxmind/geoip2-node": "^3.4.0"
|
"@maxmind/geoip2-node": "^3.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/core": {
|
|
||||||
"version": "7.21.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.21.1.tgz",
|
|
||||||
"integrity": "sha512-Og5wEEsy24fNvT/T7IKjcV4EvVK5ryY2kxbJzKY6GU2eX+i+aBl+n/vp7U0Es351C/AlTkS+0NOUsp2TQQFxZA==",
|
|
||||||
"dependencies": {
|
|
||||||
"@sentry/types": "7.21.1",
|
|
||||||
"@sentry/utils": "7.21.1",
|
|
||||||
"tslib": "^1.9.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@protobufjs/aspromise": {
|
"node_modules/@protobufjs/aspromise": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||||
@@ -2905,27 +2892,10 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/node": {
|
"node_modules/@sentry/core": {
|
||||||
"version": "7.19.0",
|
"version": "7.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.21.1.tgz",
|
||||||
"integrity": "sha512-yG7Tx32WqOkEHVotFLrumCcT9qlaSDTkFNZ+yLSvZXx74ifsE781DzBA9W7K7bBdYO3op+p2YdsOKzf3nPpAyQ==",
|
"integrity": "sha512-Og5wEEsy24fNvT/T7IKjcV4EvVK5ryY2kxbJzKY6GU2eX+i+aBl+n/vp7U0Es351C/AlTkS+0NOUsp2TQQFxZA==",
|
||||||
"dependencies": {
|
|
||||||
"@sentry/core": "7.19.0",
|
|
||||||
"@sentry/types": "7.19.0",
|
|
||||||
"@sentry/utils": "7.19.0",
|
|
||||||
"cookie": "^0.4.1",
|
|
||||||
"https-proxy-agent": "^5.0.0",
|
|
||||||
"lru_map": "^0.3.3",
|
|
||||||
"tslib": "^1.9.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@sentry/node/node_modules/@sentry/core": {
|
|
||||||
"version": "7.19.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.19.0.tgz",
|
|
||||||
"integrity": "sha512-YF9cTBcAnO4R44092BJi5Wa2/EO02xn2ziCtmNgAVTN2LD31a/YVGxGBt/FDr4Y6yeuVehaqijVVvtpSmXrGJw==",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/types": "7.21.1",
|
"@sentry/types": "7.21.1",
|
||||||
"@sentry/utils": "7.21.1",
|
"@sentry/utils": "7.21.1",
|
||||||
@@ -2986,26 +2956,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/types": {
|
|
||||||
"version": "7.21.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.21.1.tgz",
|
|
||||||
"integrity": "sha512-3/IKnd52Ol21amQvI+kz+WB76s8/LR5YvFJzMgIoI2S8d82smIr253zGijRXxHPEif8kMLX4Yt+36VzrLxg6+A==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@sentry/utils": {
|
|
||||||
"version": "7.21.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.21.1.tgz",
|
|
||||||
"integrity": "sha512-F0W0AAi8tgtTx6ApZRI2S9HbXEA9ENX1phTZgdNNWcMFm1BNbc21XEwLqwXBNjub5nlA6CE8xnjXRgdZKx4kzQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@sentry/types": "7.21.1",
|
|
||||||
"tslib": "^1.9.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@sinclair/typebox": {
|
"node_modules/@sinclair/typebox": {
|
||||||
"version": "0.24.51",
|
"version": "0.24.51",
|
||||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
|
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
|
||||||
@@ -14306,16 +14256,6 @@
|
|||||||
"@maxmind/geoip2-node": "^3.4.0"
|
"@maxmind/geoip2-node": "^3.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/core": {
|
|
||||||
"version": "7.21.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.21.1.tgz",
|
|
||||||
"integrity": "sha512-Og5wEEsy24fNvT/T7IKjcV4EvVK5ryY2kxbJzKY6GU2eX+i+aBl+n/vp7U0Es351C/AlTkS+0NOUsp2TQQFxZA==",
|
|
||||||
"requires": {
|
|
||||||
"@sentry/types": "7.21.1",
|
|
||||||
"@sentry/utils": "7.21.1",
|
|
||||||
"tslib": "^1.9.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@protobufjs/aspromise": {
|
"@protobufjs/aspromise": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||||
@@ -14370,6 +14310,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
||||||
},
|
},
|
||||||
|
"@sentry/core": {
|
||||||
|
"version": "7.21.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.21.1.tgz",
|
||||||
|
"integrity": "sha512-Og5wEEsy24fNvT/T7IKjcV4EvVK5ryY2kxbJzKY6GU2eX+i+aBl+n/vp7U0Es351C/AlTkS+0NOUsp2TQQFxZA==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/types": "7.21.1",
|
||||||
|
"@sentry/utils": "7.21.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@sentry/node": {
|
"@sentry/node": {
|
||||||
"version": "7.21.1",
|
"version": "7.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.21.1.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.21.1.tgz",
|
||||||
@@ -14409,20 +14359,6 @@
|
|||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/types": {
|
|
||||||
"version": "7.21.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.21.1.tgz",
|
|
||||||
"integrity": "sha512-3/IKnd52Ol21amQvI+kz+WB76s8/LR5YvFJzMgIoI2S8d82smIr253zGijRXxHPEif8kMLX4Yt+36VzrLxg6+A=="
|
|
||||||
},
|
|
||||||
"@sentry/utils": {
|
|
||||||
"version": "7.21.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.21.1.tgz",
|
|
||||||
"integrity": "sha512-F0W0AAi8tgtTx6ApZRI2S9HbXEA9ENX1phTZgdNNWcMFm1BNbc21XEwLqwXBNjub5nlA6CE8xnjXRgdZKx4kzQ==",
|
|
||||||
"requires": {
|
|
||||||
"@sentry/types": "7.21.1",
|
|
||||||
"tslib": "^1.9.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@sinclair/typebox": {
|
"@sinclair/typebox": {
|
||||||
"version": "0.24.51",
|
"version": "0.24.51",
|
||||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
|
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
|
||||||
|
|||||||
@@ -40,14 +40,16 @@ export const oAuthExchange = async (
|
|||||||
throw new Error("Failed to get environments")
|
throw new Error("Failed to get environments")
|
||||||
}
|
}
|
||||||
|
|
||||||
const integrationDetails = await IntegrationService.handleOAuthExchange({
|
const integrationAuth = await IntegrationService.handleOAuthExchange({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
integration,
|
integration,
|
||||||
code,
|
code,
|
||||||
environment: environments[0].slug,
|
environment: environments[0].slug,
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(200).send(integrationDetails);
|
return res.status(200).send({
|
||||||
|
integrationAuth
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Sentry.setUser({ email: req.user.email });
|
Sentry.setUser({ email: req.user.email });
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
import { Types } from 'mongoose';
|
||||||
import * as Sentry from '@sentry/node';
|
import * as Sentry from '@sentry/node';
|
||||||
import {
|
import {
|
||||||
Integration,
|
Integration,
|
||||||
@@ -16,20 +17,31 @@ import { eventPushSecrets } from '../../events';
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const createIntegration = async (req: Request, res: Response) => {
|
export const createIntegration = async (req: Request, res: Response) => {
|
||||||
|
|
||||||
// TODO: make this more versatile
|
|
||||||
|
|
||||||
let integration;
|
let integration;
|
||||||
try {
|
try {
|
||||||
|
const {
|
||||||
|
integrationAuthId,
|
||||||
|
app,
|
||||||
|
appId,
|
||||||
|
isActive,
|
||||||
|
targetEnvironment,
|
||||||
|
owner
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
// initialize new integration after saving integration access token
|
// initialize new integration after saving integration access token
|
||||||
integration = await new Integration({
|
integration = await new Integration({
|
||||||
workspace: req.integrationAuth.workspace._id,
|
workspace: req.integrationAuth.workspace._id,
|
||||||
isActive: false,
|
|
||||||
app: null,
|
|
||||||
environment: req.integrationAuth.workspace?.environments[0].slug,
|
environment: req.integrationAuth.workspace?.environments[0].slug,
|
||||||
|
isActive,
|
||||||
|
app,
|
||||||
|
appId,
|
||||||
|
targetEnvironment,
|
||||||
integration: req.integrationAuth.integration,
|
integration: req.integrationAuth.integration,
|
||||||
integrationAuth: req.integrationAuth._id
|
integrationAuth: new Types.ObjectId(integrationAuthId)
|
||||||
}).save();
|
}).save();
|
||||||
|
|
||||||
|
// TODO: run sync function
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Sentry.setUser({ email: req.user.email });
|
Sentry.setUser({ email: req.user.email });
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ interface Update {
|
|||||||
* @param {String} obj.workspaceId - id of workspace
|
* @param {String} obj.workspaceId - id of workspace
|
||||||
* @param {String} obj.integration - name of integration
|
* @param {String} obj.integration - name of integration
|
||||||
* @param {String} obj.code - code
|
* @param {String} obj.code - code
|
||||||
|
* @returns {IntegrationAuth} integrationAuth - integration auth after OAuth2 code-token exchange
|
||||||
*/
|
*/
|
||||||
const handleOAuthExchangeHelper = async ({
|
const handleOAuthExchangeHelper = async ({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -44,7 +45,7 @@ const handleOAuthExchangeHelper = async ({
|
|||||||
}) => {
|
}) => {
|
||||||
let action;
|
let action;
|
||||||
let integrationAuth;
|
let integrationAuth;
|
||||||
let newIntegration;
|
// let newIntegration;
|
||||||
try {
|
try {
|
||||||
const bot = await Bot.findOne({
|
const bot = await Bot.findOne({
|
||||||
workspace: workspaceId,
|
workspace: workspaceId,
|
||||||
@@ -100,25 +101,22 @@ const handleOAuthExchangeHelper = async ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize new integration after exchange
|
// // initialize new integration after exchange
|
||||||
newIntegration = await new Integration({
|
// newIntegration = await new Integration({
|
||||||
workspace: workspaceId,
|
// workspace: workspaceId,
|
||||||
isActive: false,
|
// isActive: false,
|
||||||
app: null,
|
// app: null,
|
||||||
environment,
|
// environment,
|
||||||
integration,
|
// integration,
|
||||||
integrationAuth: integrationAuth._id
|
// integrationAuth: integrationAuth._id
|
||||||
}).save();
|
// }).save();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Sentry.setUser(null);
|
Sentry.setUser(null);
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
throw new Error('Failed to handle OAuth2 code-token exchange')
|
throw new Error('Failed to handle OAuth2 code-token exchange')
|
||||||
}
|
}
|
||||||
|
|
||||||
return ({
|
return integrationAuth;
|
||||||
integrationAuth,
|
|
||||||
integration: newIntegration
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Sync/push environment variables in workspace with id [workspaceId] to
|
* Sync/push environment variables in workspace with id [workspaceId] to
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { ADMIN, MEMBER } from '../../variables';
|
|||||||
import { body, param } from 'express-validator';
|
import { body, param } from 'express-validator';
|
||||||
import { integrationController } from '../../controllers/v1';
|
import { integrationController } from '../../controllers/v1';
|
||||||
|
|
||||||
router.post( // new: add new integration
|
router.post( // new: add new integration for integration auth
|
||||||
'/',
|
'/',
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: ['jwt', 'apiKey']
|
acceptedAuthModes: ['jwt', 'apiKey']
|
||||||
@@ -19,7 +19,12 @@ router.post( // new: add new integration
|
|||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
location: 'body'
|
location: 'body'
|
||||||
}),
|
}),
|
||||||
body('integrationAuthId').exists().trim(),
|
body('integrationAuthId').exists().isString().trim(),
|
||||||
|
body('app').isString().trim(),
|
||||||
|
body('isActive').exists().isBoolean(),
|
||||||
|
body('appId').trim(),
|
||||||
|
body('targetEnvironment').trim(),
|
||||||
|
body('owner').trim(),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
integrationController.createIntegration
|
integrationController.createIntegration
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -26,10 +26,7 @@ class IntegrationService {
|
|||||||
* @param {String} obj1.environment - workspace environment
|
* @param {String} obj1.environment - workspace environment
|
||||||
* @param {String} obj1.integration - name of integration
|
* @param {String} obj1.integration - name of integration
|
||||||
* @param {String} obj1.code - code
|
* @param {String} obj1.code - code
|
||||||
* @returns {Object} obj2
|
* @returns {IntegrationAuth} integrationAuth - integration authorization after OAuth2 code-token exchange
|
||||||
* @returns {IntegrationAuth} obj2.integrationAuth - integration authorization after OAuth2 code-token exchange
|
|
||||||
* @returns {Integration} obj2.integration - newly-initialized integration OAuth2 code-token exchange
|
|
||||||
* @retrun
|
|
||||||
*/
|
*/
|
||||||
static async handleOAuthExchange({
|
static async handleOAuthExchange({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export {
|
|||||||
useDeleteWorkspace,
|
useDeleteWorkspace,
|
||||||
useDeleteWsEnvironment,
|
useDeleteWsEnvironment,
|
||||||
useGetUserWorkspaces,
|
useGetUserWorkspaces,
|
||||||
|
useGetWorkspaceById,
|
||||||
useRenameWorkspace,
|
useRenameWorkspace,
|
||||||
useUpdateWsEnvironment
|
useUpdateWsEnvironment
|
||||||
} from './queries';
|
} from './queries';
|
||||||
|
|||||||
@@ -11,16 +11,30 @@ import {
|
|||||||
Workspace
|
Workspace
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
|
|
||||||
const workspaceKeys = {
|
const workspaceKeys = {
|
||||||
|
getWorkspaceById: (workspaceId: string) => [{ workspaceId }, 'workspace'] as const,
|
||||||
getAllUserWorkspace: ['workspaces'] as const
|
getAllUserWorkspace: ['workspaces'] as const
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchWorkspaceById = async (workspaceId: string) => {
|
||||||
|
const { data } = await apiRequest.get<{ workspace: Workspace }>(`/api/v1/workspace/${workspaceId}`);
|
||||||
|
return data.workspace;
|
||||||
|
}
|
||||||
|
|
||||||
const fetchUserWorkspaces = async () => {
|
const fetchUserWorkspaces = async () => {
|
||||||
const { data } = await apiRequest.get<{ workspaces: Workspace[] }>('/api/v1/workspace');
|
const { data } = await apiRequest.get<{ workspaces: Workspace[] }>('/api/v1/workspace');
|
||||||
|
|
||||||
return data.workspaces;
|
return data.workspaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useGetWorkspaceById = (workspaceId: string) => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: workspaceKeys.getWorkspaceById(workspaceId),
|
||||||
|
queryFn: () => fetchWorkspaceById(workspaceId),
|
||||||
|
enabled: true
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const useGetUserWorkspaces = () =>
|
export const useGetUserWorkspaces = () =>
|
||||||
useQuery(workspaceKeys.getAllUserWorkspace, fetchUserWorkspaces);
|
useQuery(workspaceKeys.getAllUserWorkspace, fetchUserWorkspaces);
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const AuthorizeIntegration = ({ workspaceId, code, integration }: Props) =>
|
|||||||
})
|
})
|
||||||
}).then(async (res) => {
|
}).then(async (res) => {
|
||||||
if (res && res.status === 200) {
|
if (res && res.status === 200) {
|
||||||
return (res.json());
|
return (await res.json()).integrationAuth;
|
||||||
}
|
}
|
||||||
console.log('Failed to authorize the integration');
|
console.log('Failed to authorize the integration');
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import SecurityClient from '@app/components/utilities/SecurityClient';
|
import SecurityClient from '@app/components/utilities/SecurityClient';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
integrationAuthId: string;
|
integrationAuthId: string;
|
||||||
|
isActive: boolean;
|
||||||
|
app: string | null;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* This route creates a new integration based on the integration authorization with id [integrationAuthId]
|
* This route creates a new integration based on the integration authorization with id [integrationAuthId]
|
||||||
@@ -10,7 +12,9 @@ interface Props {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const createIntegration = ({
|
const createIntegration = ({
|
||||||
integrationAuthId
|
integrationAuthId,
|
||||||
|
isActive,
|
||||||
|
app
|
||||||
}: Props) =>
|
}: Props) =>
|
||||||
SecurityClient.fetchCall('/api/v1/integration', {
|
SecurityClient.fetchCall('/api/v1/integration', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -18,7 +22,9 @@ const createIntegration = ({
|
|||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
integrationAuthId
|
integrationAuthId,
|
||||||
|
isActive,
|
||||||
|
app
|
||||||
})
|
})
|
||||||
}).then(async (res) => {
|
}).then(async (res) => {
|
||||||
if (res && res.status === 200) {
|
if (res && res.status === 200) {
|
||||||
|
|||||||
@@ -13,71 +13,54 @@ import {
|
|||||||
Select,
|
Select,
|
||||||
SelectItem
|
SelectItem
|
||||||
} from '../components/v2';
|
} from '../components/v2';
|
||||||
|
import { useGetWorkspaceById } from '../hooks/api/workspace';
|
||||||
import AuthorizeIntegration from './api/integrations/authorizeIntegration';
|
import AuthorizeIntegration from './api/integrations/authorizeIntegration';
|
||||||
import updateIntegration from './api/integrations/updateIntegration';
|
import createIntegration from './api/integrations/createIntegration';
|
||||||
import getAWorkspace from './api/workspace/getAWorkspace';
|
|
||||||
|
|
||||||
interface Integration {
|
interface IntegrationAuth {
|
||||||
_id: string;
|
_id: string;
|
||||||
isActive: boolean;
|
integration: string;
|
||||||
app: string | null;
|
workspace: string;
|
||||||
appId: string | null;
|
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
environment: string;
|
|
||||||
integration: string;
|
|
||||||
targetEnvironment: string;
|
|
||||||
workspace: string;
|
|
||||||
integrationAuth: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AzureKeyVault() {
|
export default function AzureKeyVault() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const workspaceResult = useGetWorkspaceById(localStorage.getItem('projectData.id') ?? '');
|
||||||
|
|
||||||
// query-string variables
|
const { code, state } = queryString.parse(router.asPath.split('?')[1]);
|
||||||
const parsedUrl = queryString.parse(router.asPath.split('?')[1]);
|
|
||||||
const {code} = parsedUrl;
|
const [integrationAuth, setIntegrationAuth] = useState<IntegrationAuth | null>(null);
|
||||||
const {state} = parsedUrl;
|
const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState('');
|
||||||
|
|
||||||
const [integration, setIntegration] = useState<Integration | null>(null);
|
|
||||||
const [environments, setEnvironments] = useState<
|
|
||||||
{
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
}[]
|
|
||||||
>([]);
|
|
||||||
const [environment, setEnvironment] = useState('');
|
|
||||||
const [vaultBaseUrl, setVaultBaseUrl] = useState('');
|
const [vaultBaseUrl, setVaultBaseUrl] = useState('');
|
||||||
const [vaultBaseUrlErrorText, setVaultBaseUrlErrorText] = useState('');
|
const [vaultBaseUrlErrorText, setVaultBaseUrlErrorText] = useState('');
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
if (state === localStorage.getItem('latestCSRFToken')) {
|
if (state !== localStorage.getItem('latestCSRFToken')) return;
|
||||||
localStorage.removeItem('latestCSRFToken');
|
localStorage.removeItem('latestCSRFToken');
|
||||||
|
|
||||||
const integrationDetails = await AuthorizeIntegration({
|
setIntegrationAuth(await AuthorizeIntegration({
|
||||||
workspaceId: localStorage.getItem('projectData.id') as string,
|
workspaceId: localStorage.getItem('projectData.id') as string,
|
||||||
code: code as string,
|
code: code as string,
|
||||||
integration: 'azure-key-vault',
|
integration: 'azure-key-vault',
|
||||||
});
|
}));
|
||||||
|
|
||||||
setIntegration(integrationDetails.integration);
|
|
||||||
|
|
||||||
const workspaceId = localStorage.getItem('projectData.id');
|
|
||||||
if (!workspaceId) return;
|
|
||||||
|
|
||||||
const workspace = await getAWorkspace(workspaceId);
|
|
||||||
setEnvironment(workspace.environments[0].slug);
|
|
||||||
setEnvironments(workspace.environments);
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Azure Key Vault integration error: ', error);
|
console.error('Azure Key Vault integration error: ', error);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (workspaceResult && workspaceResult.data) {
|
||||||
|
setSelectedSourceEnvironment(workspaceResult.data.environments[0].slug);
|
||||||
|
}
|
||||||
|
}, [workspaceResult]);
|
||||||
|
|
||||||
const handleButtonClick = async () => {
|
const handleButtonClick = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -94,17 +77,13 @@ export default function AzureKeyVault() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!integration) return;
|
if (!integrationAuth?._id) return;
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
await updateIntegration({
|
await createIntegration({
|
||||||
integrationId: integration._id,
|
integrationAuthId: integrationAuth?._id,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
environment,
|
app: vaultBaseUrl
|
||||||
app: vaultBaseUrl,
|
|
||||||
appId: null,
|
|
||||||
targetEnvironment: null,
|
|
||||||
owner: null
|
|
||||||
});
|
});
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
||||||
@@ -117,7 +96,11 @@ export default function AzureKeyVault() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (integration && environments.length > 0) ? (
|
if (!workspaceResult) return <div />
|
||||||
|
|
||||||
|
const { data: w } = workspaceResult;
|
||||||
|
|
||||||
|
return (integrationAuth && w && selectedSourceEnvironment) ? (
|
||||||
<div className="h-full w-full flex justify-center items-center">
|
<div className="h-full w-full flex justify-center items-center">
|
||||||
<Card className="max-w-md p-8 rounded-md">
|
<Card className="max-w-md p-8 rounded-md">
|
||||||
<CardTitle className='text-center'>Azure Key Vault Integration</CardTitle>
|
<CardTitle className='text-center'>Azure Key Vault Integration</CardTitle>
|
||||||
@@ -126,13 +109,13 @@ export default function AzureKeyVault() {
|
|||||||
className='mt-4'
|
className='mt-4'
|
||||||
>
|
>
|
||||||
<Select
|
<Select
|
||||||
value={environment}
|
value={selectedSourceEnvironment}
|
||||||
onValueChange={(val) => setEnvironment(val)}
|
onValueChange={(val) => setSelectedSourceEnvironment(val)}
|
||||||
className='w-full border border-mineshaft-500'
|
className='w-full border border-mineshaft-500'
|
||||||
>
|
>
|
||||||
{environments.map((e) => (
|
{w?.environments.map((sourceEnvironment) => (
|
||||||
<SelectItem value={e.slug} key={`azure-key-vault-environment-${e.slug}`}>
|
<SelectItem value={sourceEnvironment.slug} key={`azure-key-vault-environment-${sourceEnvironment.slug}`}>
|
||||||
{e.name}
|
{sourceEnvironment.name}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
|
|||||||
+131
-13
@@ -1,41 +1,159 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import queryString from 'query-string';
|
import queryString from 'query-string';
|
||||||
|
|
||||||
|
import { getTranslatedServerSideProps } from '@app/components/utilities/withTranslateProps';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
CardTitle,
|
||||||
|
FormControl,
|
||||||
|
Select,
|
||||||
|
SelectItem
|
||||||
|
} from '../components/v2';
|
||||||
import AuthorizeIntegration from './api/integrations/authorizeIntegration';
|
import AuthorizeIntegration from './api/integrations/authorizeIntegration';
|
||||||
|
import getIntegrationApps from './api/integrations/GetIntegrationApps';
|
||||||
|
import getAWorkspace from './api/workspace/getAWorkspace';
|
||||||
|
|
||||||
|
interface Integration {
|
||||||
|
_id: string;
|
||||||
|
isActive: boolean;
|
||||||
|
app: string | null;
|
||||||
|
appId: string | null;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
environment: string;
|
||||||
|
integration: string;
|
||||||
|
targetEnvironment: string;
|
||||||
|
workspace: string;
|
||||||
|
integrationAuth: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IntegrationApp {
|
||||||
|
name: string;
|
||||||
|
appId?: string;
|
||||||
|
owner?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function Heroku() {
|
export default function Heroku() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const parsedUrl = queryString.parse(router.asPath.split('?')[1]);
|
const parsedUrl = queryString.parse(router.asPath.split('?')[1]);
|
||||||
const {code} = parsedUrl;
|
const { code } = parsedUrl;
|
||||||
const {state} = parsedUrl;
|
const { state } = parsedUrl;
|
||||||
|
|
||||||
|
const [integration, setIntegration] = useState<Integration | null>(null);
|
||||||
|
const [environments, setEnvironments] = useState<
|
||||||
|
{
|
||||||
|
name: string;
|
||||||
|
slug: string;
|
||||||
|
}[]
|
||||||
|
>([]);
|
||||||
|
const [environment, setEnvironment] = useState('');
|
||||||
|
const [app, setApp] = useState('');
|
||||||
|
const [apps, setApps] = useState<IntegrationApp[]>([]);
|
||||||
|
|
||||||
/**
|
|
||||||
* Here we forward to the default workspace if a user opens this url
|
|
||||||
*/
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
if (state === localStorage.getItem('latestCSRFToken')) {
|
if (state === localStorage.getItem('latestCSRFToken')) {
|
||||||
localStorage.removeItem('latestCSRFToken');
|
localStorage.removeItem('latestCSRFToken');
|
||||||
await AuthorizeIntegration({
|
const integrationDetails = await AuthorizeIntegration({
|
||||||
workspaceId: localStorage.getItem('projectData.id') as string,
|
workspaceId: localStorage.getItem('projectData.id') as string,
|
||||||
code: code as string,
|
code: code as string,
|
||||||
integration: 'heroku',
|
integration: 'heroku',
|
||||||
});
|
});
|
||||||
router.push(
|
|
||||||
`/integrations/${ localStorage.getItem('projectData.id')}`
|
setIntegration(integrationDetails.integration);
|
||||||
);
|
|
||||||
|
const workspaceId = localStorage.getItem('projectData.id');
|
||||||
|
if (!workspaceId) return;
|
||||||
|
|
||||||
|
const workspace = await getAWorkspace(workspaceId);
|
||||||
|
setEnvironment(workspace.environments[0].slug);
|
||||||
|
setEnvironments(workspace.environments);
|
||||||
|
|
||||||
|
const tempApps: [IntegrationApp] = await getIntegrationApps({
|
||||||
|
integrationAuthId: integrationDetails.integration.integrationAuth
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('tempApps: ', tempApps);
|
||||||
|
setApp(tempApps[0].name);
|
||||||
|
setApps(tempApps);
|
||||||
|
|
||||||
|
// router.push(
|
||||||
|
// `/integrations/${ localStorage.getItem('projectData.id')}`
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Heroku integration error: ', error);
|
console.error('Heroku integration error: ', error);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleButtonClick = async () => {
|
||||||
|
try {
|
||||||
|
console.log('handleButtonClick');
|
||||||
|
console.log('project environment: ', environment);
|
||||||
|
console.log('app', app);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('integration: ', integration);
|
||||||
|
console.log('environments: ', environments);
|
||||||
|
console.log('apps: ', apps);
|
||||||
|
|
||||||
return <div />;
|
return (integration && environments.length > 0 && apps.length > 0) ? (
|
||||||
|
<div className="h-full w-full flex justify-center items-center">
|
||||||
|
<Card className="max-w-md p-8 rounded-md">
|
||||||
|
<CardTitle className='text-center'>Heroku Integration</CardTitle>
|
||||||
|
<FormControl
|
||||||
|
label="Project Environment"
|
||||||
|
className='mt-4'
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
value={environment}
|
||||||
|
onValueChange={(val) => setEnvironment(val)}
|
||||||
|
className='w-full border border-mineshaft-500'
|
||||||
|
>
|
||||||
|
{environments.map((e) => (
|
||||||
|
<SelectItem value={e.slug} key={`heroku-environment-${e.slug}`}>
|
||||||
|
{e.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl
|
||||||
|
label="Heroku App"
|
||||||
|
className='mt-4'
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
value={app}
|
||||||
|
onValueChange={(val) => setApp(val)}
|
||||||
|
className='w-full border border-mineshaft-500'
|
||||||
|
>
|
||||||
|
{apps.map((a) => (
|
||||||
|
<SelectItem value={a.name} key={`heroku-environment-${a.name}`}>
|
||||||
|
{a.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<Button
|
||||||
|
onClick={handleButtonClick}
|
||||||
|
color="mineshaft"
|
||||||
|
className='mt-4'
|
||||||
|
isLoading={isLoading}
|
||||||
|
>
|
||||||
|
Create Integration
|
||||||
|
</Button>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
) : <div>Hello</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
Heroku.requireAuth = true;
|
Heroku.requireAuth = true;
|
||||||
|
|
||||||
|
export const getServerSideProps = getTranslatedServerSideProps(['integrations']);
|
||||||
@@ -235,7 +235,9 @@ export default function Integrations() {
|
|||||||
setIntegrationAuths([...integrationAuths, integrationAuth])
|
setIntegrationAuths([...integrationAuths, integrationAuth])
|
||||||
|
|
||||||
const integration = await createIntegration({
|
const integration = await createIntegration({
|
||||||
integrationAuthId: integrationAuth._id
|
integrationAuthId: integrationAuth._id,
|
||||||
|
isActive: false,
|
||||||
|
app: null
|
||||||
});
|
});
|
||||||
|
|
||||||
setIntegrations([...integrations, integration]);
|
setIntegrations([...integrations, integration]);
|
||||||
|
|||||||
Reference in New Issue
Block a user