feat: changed line length to 120

This commit is contained in:
Akhil Mohan
2024-01-30 22:40:10 +05:30
parent 5855cc660a
commit bcbb49ed1b
142 changed files with 1183 additions and 3706 deletions
@@ -22,11 +22,7 @@ const getAppsGCPSecretManager = async ({ accessToken }: { accessToken: string })
interface GCPApp {
projectNumber: string;
projectId: string;
lifecycleState:
| "ACTIVE"
| "LIFECYCLE_STATE_UNSPECIFIED"
| "DELETE_REQUESTED"
| "DELETE_IN_PROGRESS";
lifecycleState: "ACTIVE" | "LIFECYCLE_STATE_UNSPECIFIED" | "DELETE_REQUESTED" | "DELETE_IN_PROGRESS";
name: string;
createTime: string;
parent: {
@@ -131,30 +127,21 @@ const getAppsHeroku = async ({ accessToken }: { accessToken: string }) => {
/**
* Return list of names of apps for Vercel integration
*/
const getAppsVercel = async ({
accessToken,
teamId
}: {
teamId?: string | null;
accessToken: string;
}) => {
const getAppsVercel = async ({ accessToken, teamId }: { teamId?: string | null; accessToken: string }) => {
const res = (
await request.get<{ projects: { name: string; id: string }[] }>(
`${IntegrationUrls.VERCEL_API_URL}/v9/projects`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
},
...(teamId
? {
params: {
teamId
}
await request.get<{ projects: { name: string; id: string }[] }>(`${IntegrationUrls.VERCEL_API_URL}/v9/projects`, {
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
},
...(teamId
? {
params: {
teamId
}
: {})
}
)
}
: {})
})
).data;
const apps = res.projects.map((a) => ({
@@ -273,16 +260,13 @@ const getAppsGithub = async ({ accessToken }: { accessToken: string }) => {
*/
const getAppsRender = async ({ accessToken }: { accessToken: string }) => {
const res = (
await request.get<{ service: { name: string; id: string } }[]>(
`${IntegrationUrls.RENDER_API_URL}/v1/services`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json",
"Accept-Encoding": "application/json"
}
await request.get<{ service: { name: string; id: string } }[]>(`${IntegrationUrls.RENDER_API_URL}/v1/services`, {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json",
"Accept-Encoding": "application/json"
}
)
})
).data;
const apps = res.map((a) => ({
@@ -346,13 +330,7 @@ const getAppsRailway = async ({ accessToken }: { accessToken: string }) => {
/**
* Return list of sites for Laravel Forge integration
*/
const getAppsLaravelForge = async ({
accessToken,
serverId
}: {
accessToken: string;
serverId?: string;
}) => {
const getAppsLaravelForge = async ({ accessToken, serverId }: { accessToken: string; serverId?: string }) => {
const res = (
await request.get<{ sites: { name: string; id: string }[] }>(
`${IntegrationUrls.LARAVELFORGE_API_URL}/api/v1/servers/${serverId}/sites`,
@@ -464,13 +442,7 @@ const getAppsTravisCI = async ({ accessToken }: { accessToken: string }) => {
/**
* Return list of projects for Terraform Cloud integration
*/
const getAppsTerraformCloud = async ({
accessToken,
workspacesId
}: {
accessToken: string;
workspacesId?: string;
}) => {
const getAppsTerraformCloud = async ({ accessToken, workspacesId }: { accessToken: string; workspacesId?: string }) => {
const res = (
await request.get<{ data: { attributes: { name: string }; id: string } }>(
`${IntegrationUrls.TERRAFORM_CLOUD_API_URL}/api/v2/workspaces/${workspacesId}`,
@@ -566,16 +538,13 @@ const getAppsGitlab = async ({
per_page: String(perPage)
});
const { data } = await request.get<{ name: string; id: string }[]>(
`${gitLabApiUrl}/v4/users/${id}/projects`,
{
params,
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
const { data } = await request.get<{ name: string; id: string }[]>(`${gitLabApiUrl}/v4/users/${id}/projects`, {
params,
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
);
});
data.forEach((a) => {
apps.push({
@@ -642,15 +611,12 @@ const getAppsSupabase = async ({ accessToken }: { accessToken: string }) => {
* Return list of accounts for the Checkly integration
*/
const getAppsCheckly = async ({ accessToken }: { accessToken: string }) => {
const { data } = await request.get<{ name: string; id: string }[]>(
`${IntegrationUrls.CHECKLY_API_URL}/v1/accounts`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
const { data } = await request.get<{ name: string; id: string }[]>(`${IntegrationUrls.CHECKLY_API_URL}/v1/accounts`, {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
);
});
const apps = data.map((a) => ({
name: a.name,
@@ -663,13 +629,7 @@ const getAppsCheckly = async ({ accessToken }: { accessToken: string }) => {
/**
* Return list of projects for the Cloudflare Pages integration
*/
const getAppsCloudflarePages = async ({
accessToken,
accountId
}: {
accessToken: string;
accountId?: string;
}) => {
const getAppsCloudflarePages = async ({ accessToken, accountId }: { accessToken: string; accountId?: string }) => {
const { data } = await request.get<{ result: { name: string; id: string }[] }>(
`${IntegrationUrls.CLOUDFLARE_PAGES_API_URL}/client/v4/accounts/${accountId}/pages/projects`,
{
@@ -690,13 +650,7 @@ const getAppsCloudflarePages = async ({
/**
* Return list of projects for the Cloudflare Workers integration
*/
const getAppsCloudflareWorkers = async ({
accessToken,
accountId
}: {
accessToken: string;
accountId?: string;
}) => {
const getAppsCloudflareWorkers = async ({ accessToken, accountId }: { accessToken: string; accountId?: string }) => {
const { data } = await request.get<{ result: { id: string }[] }>(
`${IntegrationUrls.CLOUDFLARE_WORKERS_API_URL}/client/v4/accounts/${accountId}/workers/services`,
{
@@ -717,13 +671,7 @@ const getAppsCloudflareWorkers = async ({
/**
* Return list of repositories for the BitBucket integration based on provided BitBucket workspace
*/
const getAppsBitBucket = async ({
accessToken,
workspaceSlug
}: {
accessToken: string;
workspaceSlug?: string;
}) => {
const getAppsBitBucket = async ({ accessToken, workspaceSlug }: { accessToken: string; workspaceSlug?: string }) => {
interface RepositoriesResponse {
size: number;
page: number;
@@ -881,25 +829,19 @@ const getAppsWindmill = async ({ accessToken }: { accessToken: string }) => {
// is write access is allowed then delete the created secrets from workspace
if (writeUser && writeFolder) {
await request.delete(
`${IntegrationUrls.WINDMILL_API_URL}/w/${app.id}/variables/delete/${userPath}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
await request.delete(`${IntegrationUrls.WINDMILL_API_URL}/w/${app.id}/variables/delete/${userPath}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
);
});
await request.delete(
`${IntegrationUrls.WINDMILL_API_URL}/w/${app.id}/variables/delete/${folderPath}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
await request.delete(`${IntegrationUrls.WINDMILL_API_URL}/w/${app.id}/variables/delete/${folderPath}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
);
});
return app;
}
@@ -910,9 +852,7 @@ const getAppsWindmill = async ({ accessToken }: { accessToken: string }) => {
});
const appsWriteResponses = await Promise.all(writeAccessCheck);
const appsWithWriteAccess = appsWriteResponses.filter(
(appRes) => !(appRes as { error: string })?.error
);
const appsWithWriteAccess = appsWriteResponses.filter((appRes) => !(appRes as { error: string })?.error);
const apps = (appsWithWriteAccess as { id: string; name: string }[]).map((a) => ({
name: a.name,
@@ -945,15 +885,12 @@ const getAppsDigitalOceanAppPlatform = async ({ accessToken }: { accessToken: st
}
const res = (
await request.get<{ apps: DigitalOceanApp[] }>(
`${IntegrationUrls.DIGITAL_OCEAN_API_URL}/v2/apps`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
await request.get<{ apps: DigitalOceanApp[] }>(`${IntegrationUrls.DIGITAL_OCEAN_API_URL}/v2/apps`, {
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
)
})
).data;
return (res.apps ?? []).map((a) => ({
@@ -1,21 +1,10 @@
import { ForbiddenError } from "@casl/ability";
import {
SecretEncryptionAlgo,
SecretKeyEncoding,
TIntegrationAuths,
TIntegrationAuthsInsert
} from "@app/db/schemas";
import { SecretEncryptionAlgo, SecretKeyEncoding, TIntegrationAuths, TIntegrationAuthsInsert } from "@app/db/schemas";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import {
ProjectPermissionActions,
ProjectPermissionSub
} from "@app/ee/services/permission/project-permission";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { request } from "@app/lib/config/request";
import {
decryptSymmetric128BitHexKeyUTF8,
encryptSymmetric128BitHexKeyUTF8
} from "@app/lib/crypto";
import { decryptSymmetric128BitHexKeyUTF8, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
import { BadRequestError } from "@app/lib/errors";
import { TProjectPermission } from "@app/lib/types";
@@ -70,16 +59,9 @@ export const integrationAuthServiceFactory = ({
projectBotDAL,
projectBotService
}: TIntegrationAuthServiceFactoryDep) => {
const listIntegrationAuthByProjectId = async ({
actorId,
actor,
projectId
}: TProjectPermission) => {
const listIntegrationAuthByProjectId = async ({ actorId, actor, projectId }: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const authorizations = await integrationAuthDAL.find({ projectId });
return authorizations;
};
@@ -88,38 +70,20 @@ export const integrationAuthServiceFactory = ({
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
return integrationAuth;
};
const oauthExchange = async ({
projectId,
actorId,
actor,
integration,
url,
code
}: TOauthExchangeDTO) => {
const oauthExchange = async ({ projectId, actorId, actor, integration, url, code }: TOauthExchangeDTO) => {
if (!Object.values(Integrations).includes(integration as Integrations))
throw new BadRequestError({ message: "Invalid integration" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create,
ProjectPermissionSub.Integrations
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
const bot = await projectBotDAL.findOne({ isActive: true, projectId });
if (!bot)
throw new BadRequestError({ message: "Bot must be enabled for oauth2 code token exchange" });
if (!bot) throw new BadRequestError({ message: "Bot must be enabled for oauth2 code token exchange" });
const tokenExchange = await exchangeCode({ integration, code, url });
const updateDoc: TIntegrationAuthsInsert = {
@@ -178,14 +142,10 @@ export const integrationAuthServiceFactory = ({
throw new BadRequestError({ message: "Invalid integration" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create,
ProjectPermissionSub.Integrations
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
const bot = await projectBotDAL.findOne({ isActive: true, projectId });
if (!bot)
throw new BadRequestError({ message: "Bot must be enabled for oauth2 code token exchange" });
if (!bot) throw new BadRequestError({ message: "Bot must be enabled for oauth2 code token exchange" });
const updateDoc: TIntegrationAuthsInsert = {
projectId,
@@ -251,11 +211,7 @@ export const integrationAuthServiceFactory = ({
});
}
if (
integrationAuth.refreshCiphertext &&
integrationAuth.refreshIV &&
integrationAuth.refreshTag
) {
if (integrationAuth.refreshCiphertext && integrationAuth.refreshIV && integrationAuth.refreshTag) {
const refreshToken = decryptSymmetric128BitHexKeyUTF8({
key: botKey,
ciphertext: integrationAuth.refreshCiphertext,
@@ -287,11 +243,7 @@ export const integrationAuthServiceFactory = ({
}
if (!accessToken) throw new BadRequestError({ message: "Missing access token" });
if (
integrationAuth.accessIdTag &&
integrationAuth.accessIdIV &&
integrationAuth.accessIdCiphertext
) {
if (integrationAuth.accessIdTag && integrationAuth.accessIdIV && integrationAuth.accessIdCiphertext) {
accessId = decryptSymmetric128BitHexKeyUTF8({
key: botKey,
ciphertext: integrationAuth.accessIdCiphertext,
@@ -302,25 +254,12 @@ export const integrationAuthServiceFactory = ({
return { accessId, accessToken };
};
const getIntegrationApps = async ({
actor,
actorId,
teamId,
id,
workspaceSlug
}: TIntegrationAuthAppsDTO) => {
const getIntegrationApps = async ({ actor, actorId, teamId, id, workspaceSlug }: TIntegrationAuthAppsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken, accessId } = await getIntegrationAccessToken(integrationAuth, botKey);
@@ -339,15 +278,8 @@ export const integrationAuthServiceFactory = ({
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
@@ -359,24 +291,12 @@ export const integrationAuthServiceFactory = ({
return teams;
};
const getVercelBranches = async ({
appId,
id,
actor,
actorId
}: TIntegrationAuthVercelBranchesDTO) => {
const getVercelBranches = async ({ appId, id, actor, actorId }: TIntegrationAuthVercelBranchesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
@@ -399,37 +319,22 @@ export const integrationAuthServiceFactory = ({
return [];
};
const getChecklyGroups = async ({
actorId,
actor,
id,
accountId
}: TIntegrationAuthChecklyGroupsDTO) => {
const getChecklyGroups = async ({ actorId, actor, id, accountId }: TIntegrationAuthChecklyGroupsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
if (accountId) {
const { data } = await request.get<TChecklyGroups[]>(
`${IntegrationUrls.CHECKLY_API_URL}/v1/check-groups`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json",
"X-Checkly-Account": accountId
}
const { data } = await request.get<TChecklyGroups[]>(`${IntegrationUrls.CHECKLY_API_URL}/v1/check-groups`, {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json",
"X-Checkly-Account": accountId
}
);
});
return data.map(({ name, id: groupId }) => ({ name, groupId }));
}
return [];
@@ -439,15 +344,8 @@ export const integrationAuthServiceFactory = ({
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
const { data } = await request.get<{ results: Array<{ id: string; name: string }> }>(
@@ -463,24 +361,12 @@ export const integrationAuthServiceFactory = ({
return data.results.map(({ name, id: orgId }) => ({ name, orgId }));
};
const getQoveryProjects = async ({
actorId,
actor,
id,
orgId
}: TIntegrationAuthQoveryProjectDTO) => {
const getQoveryProjects = async ({ actorId, actor, id, orgId }: TIntegrationAuthQoveryProjectDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
if (orgId) {
@@ -498,24 +384,12 @@ export const integrationAuthServiceFactory = ({
return [];
};
const getQoveryEnvs = async ({
projectId,
id,
actor,
actorId
}: TIntegrationAuthQoveryEnvironmentsDTO) => {
const getQoveryEnvs = async ({ projectId, id, actor, actorId }: TIntegrationAuthQoveryEnvironmentsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
if (projectId && projectId !== "none") {
@@ -538,24 +412,12 @@ export const integrationAuthServiceFactory = ({
return [];
};
const getQoveryApps = async ({
id,
actor,
actorId,
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const getQoveryApps = async ({ id, actor, actorId, environmentId }: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
if (environmentId) {
@@ -577,24 +439,12 @@ export const integrationAuthServiceFactory = ({
return [];
};
const getQoveryContainers = async ({
id,
actor,
actorId,
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const getQoveryContainers = async ({ id, actor, actorId, environmentId }: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
if (environmentId) {
@@ -616,24 +466,12 @@ export const integrationAuthServiceFactory = ({
return [];
};
const getQoveryJobs = async ({
id,
actor,
actorId,
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const getQoveryJobs = async ({ id, actor, actorId, environmentId }: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
if (environmentId) {
@@ -655,24 +493,12 @@ export const integrationAuthServiceFactory = ({
return [];
};
const getRailwayEnvironments = async ({
id,
actor,
actorId,
appId
}: TIntegrationAuthRailwayEnvDTO) => {
const getRailwayEnvironments = async ({ id, actor, actorId, appId }: TIntegrationAuthRailwayEnvDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
if (appId) {
@@ -721,24 +547,12 @@ export const integrationAuthServiceFactory = ({
}
return [];
};
const getRailwayServices = async ({
id,
actor,
actorId,
appId
}: TIntegrationAuthRailwayServicesDTO) => {
const getRailwayServices = async ({ id, actor, actorId, appId }: TIntegrationAuthRailwayServicesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
if (appId) {
@@ -806,23 +620,12 @@ export const integrationAuthServiceFactory = ({
return [];
};
const getBitbucketWorkspaces = async ({
actorId,
actor,
id
}: TIntegrationAuthBitbucketWorkspaceDTO) => {
const getBitbucketWorkspaces = async ({ actorId, actor, id }: TIntegrationAuthBitbucketWorkspaceDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
const workspaces: TBitbucketWorkspace[] = [];
@@ -834,12 +637,11 @@ export const integrationAuthServiceFactory = ({
const { data }: { data: { values: TBitbucketWorkspace[]; next: string } } = await request.get(
workspaceUrl,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
);
});
if (data?.values.length > 0) {
data.values.forEach((workspace) => {
@@ -856,24 +658,12 @@ export const integrationAuthServiceFactory = ({
return workspaces;
};
const getNorthFlankSecretGroups = async ({
id,
actor,
actorId,
appId
}: TIntegrationAuthNorthflankSecretGroupDTO) => {
const getNorthFlankSecretGroups = async ({ id, actor, actorId, appId }: TIntegrationAuthNorthflankSecretGroupDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
const secretGroups: { name: string; groupId: string }[] = [];
@@ -923,41 +713,26 @@ export const integrationAuthServiceFactory = ({
return secretGroups;
};
const getTeamcityBuildConfigs = async ({
appId,
id,
actorId,
actor
}: TGetIntegrationAuthTeamCityBuildConfigDTO) => {
const getTeamcityBuildConfigs = async ({ appId, id, actorId, actor }: TGetIntegrationAuthTeamCityBuildConfigDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const botKey = await projectBotService.getBotKey(integrationAuth.projectId);
const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey);
if (appId) {
const {
data: { buildType }
} = await request.get<{ buildType: TTeamCityBuildConfig[] }>(
`${integrationAuth.url}/app/rest/buildTypes`,
{
params: {
locator: `project:${appId}`
},
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
} = await request.get<{ buildType: TTeamCityBuildConfig[] }>(`${integrationAuth.url}/app/rest/buildTypes`, {
params: {
locator: `project:${appId}`
},
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
);
});
return buildType.map(({ name, id: buildConfigId }) => ({
name,
@@ -967,39 +742,20 @@ export const integrationAuthServiceFactory = ({
return [];
};
const deleteIntegrationAuths = async ({
projectId,
integration,
actor,
actorId
}: TDeleteIntegrationAuthsDTO) => {
const deleteIntegrationAuths = async ({ projectId, integration, actor, actorId }: TDeleteIntegrationAuthsDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete,
ProjectPermissionSub.Integrations
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
const integrations = await integrationAuthDAL.delete({ integration, projectId });
return integrations;
};
const deleteIntegrationAuthById = async ({
id,
actorId,
actor
}: TDeleteIntegrationAuthByIdDTO) => {
const deleteIntegrationAuthById = async ({ id, actorId, actor }: TDeleteIntegrationAuthByIdDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete,
ProjectPermissionSub.Integrations
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
const delIntegrationAuth = await integrationAuthDAL.transaction(async (tx) => {
const doc = await integrationAuthDAL.deleteById(integrationAuth.id, tx);
@@ -26,9 +26,7 @@ import { BadRequestError } from "@app/lib/errors";
import { Integrations, IntegrationUrls } from "./integration-list";
const getSecretKeyValuePair = (
secrets: Record<string, { value: string | null; comment?: string } | null>
) =>
const getSecretKeyValuePair = (secrets: Record<string, { value: string | null; comment?: string } | null>) =>
Object.keys(secrets).reduce<Record<string, string | null | undefined>>((prev, key) => {
// eslint-disable-next-line
prev[key] = secrets?.[key] === null ? null : secrets?.[key]?.value;
@@ -289,9 +287,7 @@ const syncSecretsAzureKeyVault = async ({
return result;
};
const getAzureKeyVaultSecrets = await paginateAzureKeyVaultSecrets(
`${integration.app}/secrets?api-version=7.3`
);
const getAzureKeyVaultSecrets = await paginateAzureKeyVaultSecrets(`${integration.app}/secrets?api-version=7.3`);
let lastSlashIndex: number;
const res = (
@@ -301,14 +297,11 @@ const syncSecretsAzureKeyVault = async ({
lastSlashIndex = getAzureKeyVaultSecret.id.lastIndexOf("/");
}
const azureKeyVaultSecret = await request.get(
`${getAzureKeyVaultSecret.id}?api-version=7.3`,
{
headers: {
Authorization: `Bearer ${accessToken}`
}
const azureKeyVaultSecret = await request.get(`${getAzureKeyVaultSecret.id}?api-version=7.3`, {
headers: {
Authorization: `Bearer ${accessToken}`
}
);
});
return {
...azureKeyVaultSecret.data,
@@ -701,11 +694,7 @@ const syncSecretsVercel = async ({
return false;
}
if (
integration.targetEnvironment === "preview" &&
secret.gitBranch &&
integration.path !== secret.gitBranch
) {
if (integration.targetEnvironment === "preview" && secret.gitBranch && integration.path !== secret.gitBranch) {
// case: secret on preview environment does not have same target git branch
return false;
}
@@ -719,16 +708,13 @@ const syncSecretsVercel = async ({
if (vercelSecret.type === "encrypted") {
// case: secret is encrypted -> need to decrypt
const decryptedSecret = (
await request.get(
`${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${vercelSecret.id}`,
{
params,
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
await request.get(`${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${vercelSecret.id}`, {
params,
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
)
})
).data;
res[vercelSecret.key] = decryptedSecret;
@@ -798,47 +784,36 @@ const syncSecretsVercel = async ({
// Sync/push new secrets
if (newSecrets.length > 0) {
await request.post(
`${IntegrationUrls.VERCEL_API_URL}/v10/projects/${integration.app}/env`,
newSecrets,
{
params,
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
await request.post(`${IntegrationUrls.VERCEL_API_URL}/v10/projects/${integration.app}/env`, newSecrets, {
params,
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
);
});
}
for await (const secret of updateSecrets) {
if (secret.type !== "sensitive") {
const { id, ...updatedSecret } = secret;
await request.patch(
`${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${id}`,
updatedSecret,
{
params,
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
}
);
}
}
for await (const secret of deleteSecrets) {
await request.delete(
`${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${secret.id}`,
{
await request.patch(`${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${id}`, updatedSecret, {
params,
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
});
}
}
for await (const secret of deleteSecrets) {
await request.delete(`${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${secret.id}`, {
params,
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
);
});
}
};
@@ -1366,9 +1341,7 @@ const syncSecretsFlyio = async ({
)
).data.data.app.secrets;
const deleteSecretsKeys = getSecretsRes
.filter((secret) => !(secret.name in secrets))
.map((secret) => secret.name);
const deleteSecretsKeys = getSecretsRes.filter((secret) => !(secret.name in secrets)).map((secret) => secret.name);
// unset (delete) secrets
const DeleteSecrets = `mutation($input: UnsetSecretsInput!) {
@@ -1593,9 +1566,7 @@ const syncSecretsGitLab = async ({
environment_scope: string;
}
const gitLabApiUrl = integrationAuth.url
? `${integrationAuth.url}/api`
: IntegrationUrls.GITLAB_API_URL;
const gitLabApiUrl = integrationAuth.url ? `${integrationAuth.url}/api` : IntegrationUrls.GITLAB_API_URL;
const getAllEnvVariables = async (integrationAppId: string, accToken: string) => {
const headers = {
@@ -1605,8 +1576,7 @@ const syncSecretsGitLab = async ({
};
let allEnvVariables: GitLabSecret[] = [];
let url: string | null =
`${gitLabApiUrl}/v4/projects/${integrationAppId}/variables?per_page=100`;
let url: string | null = `${gitLabApiUrl}/v4/projects/${integrationAppId}/variables?per_page=100`;
while (url) {
const response = await request.get(url, { headers });
@@ -1740,29 +1710,21 @@ const syncSecretsSupabase = async ({
if (
!(secretObj.name in secrets) &&
// supbase reserved secret ref: https://supabase.com/docs/guides/functions/secrets#default-secrets
![
"SUPABASE_ANON_KEY",
"SUPABASE_SERVICE_ROLE_KEY",
"SUPABASE_DB_URL",
"SUPABASE_URL"
].includes(secretObj.name)
!["SUPABASE_ANON_KEY", "SUPABASE_SERVICE_ROLE_KEY", "SUPABASE_DB_URL", "SUPABASE_URL"].includes(secretObj.name)
) {
return secretObj.name;
}
return [];
});
await request.delete(
`${IntegrationUrls.SUPABASE_API_URL}/v1/projects/${integration.appId}/secrets`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
"Accept-Encoding": "application/json"
},
data: secretsToDelete
}
);
await request.delete(`${IntegrationUrls.SUPABASE_API_URL}/v1/projects/${integration.appId}/secrets`, {
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
"Accept-Encoding": "application/json"
},
data: secretsToDelete
});
};
/**
@@ -1841,16 +1803,13 @@ const syncSecretsCheckly = async ({
// sync secrets to checkly global envars
let getSecretsRes = (
await request.get<{ key: string; value: string }[]>(
`${IntegrationUrls.CHECKLY_API_URL}/v1/variables`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json",
"X-Checkly-Account": integration.appId
}
await request.get<{ key: string; value: string }[]>(`${IntegrationUrls.CHECKLY_API_URL}/v1/variables`, {
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json",
"X-Checkly-Account": integration.appId
}
)
})
).data.reduce(
(obj, secret) => ({
...obj,
@@ -2260,15 +2219,12 @@ const syncSecretsTeamCity = async ({
for await (const key of Object.keys(res)) {
if (!(key in secrets)) {
// delete secret
await request.delete(
`${integrationAuth.url}/app/rest/projects/id:${integration.appId}/parameters/env.${key}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
await request.delete(`${integrationAuth.url}/app/rest/projects/id:${integration.appId}/parameters/env.${key}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
);
});
}
}
}
@@ -2353,15 +2309,12 @@ const syncSecretsCloudflarePages = async ({
const getSecretsRes = (
await request.get<{
result: { deployment_configs: Record<string, { env_vars: Record<string, unknown> }> };
}>(
`${IntegrationUrls.CLOUDFLARE_PAGES_API_URL}/client/v4/accounts/${accessId}/pages/projects/${integration.app}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
}>(`${IntegrationUrls.CLOUDFLARE_PAGES_API_URL}/client/v4/accounts/${accessId}/pages/projects/${integration.app}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
)
})
).data.result.deployment_configs[integration.targetEnvironment as string].env_vars;
// copy the secrets object, so we can set deleted keys to null
@@ -2420,10 +2373,7 @@ const syncSecretsCloudflareWorkers = async ({
).data.result;
const secretsObj = Object.fromEntries(
Object.entries(getSecretKeyValuePair(secrets)).map(([key, val]) => [
key,
{ type: "secret_text", value: val }
])
Object.entries(getSecretKeyValuePair(secrets)).map(([key, val]) => [key, { type: "secret_text", value: val }])
);
// get deleted secrets list
@@ -2463,13 +2413,11 @@ const syncSecretsCloudflareWorkers = async ({
};
}
const data: ConvertedSecret[] = Object.entries(secretsObj as SecretsObj).map(
([name, secret]) => ({
name,
text: secret.value,
type: "secret_text"
})
);
const data: ConvertedSecret[] = Object.entries(secretsObj as SecretsObj).map(([name, secret]) => ({
name,
text: secret.value,
type: "secret_text"
}));
await Promise.all(
data.map(async (secret) => {
@@ -2697,15 +2645,12 @@ const syncSecretsWindmill = async ({
// get secrets stored in windmill workspace
const res = (
await request.get<WindmillSecret[]>(
`${IntegrationUrls.WINDMILL_API_URL}/w/${integration.appId}/variables/list`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
await request.get<WindmillSecret[]>(`${IntegrationUrls.WINDMILL_API_URL}/w/${integration.appId}/variables/list`, {
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
)
})
).data.reduce(
(obj, secret) => ({
...obj,
@@ -2858,15 +2803,12 @@ const syncSecretsCloud66 = async ({
for await (const key of Object.keys(res)) {
if (!(key in secrets)) {
// delete secret
await request.delete(
`${IntegrationUrls.CLOUD_66_API_URL}/3/stacks/${integration.appId}/environments/${key}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
await request.delete(`${IntegrationUrls.CLOUD_66_API_URL}/3/stacks/${integration.appId}/environments/${key}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
}
);
});
}
}
};
@@ -2920,8 +2862,7 @@ const syncSecretsHasuraCloud = async ({
const res = await request.post(
IntegrationUrls.HASURA_CLOUD_API_URL,
{
query:
"query MyQuery($tenantId: uuid!) { getTenantEnv(tenantId: $tenantId) { hash envVars } }",
query: "query MyQuery($tenantId: uuid!) { getTenantEnv(tenantId: $tenantId) { hash envVars } }",
variables: {
tenantId: integration.appId
}
@@ -518,13 +518,7 @@ const exchangeRefreshHeroku = async ({ refreshToken }: { refreshToken: string })
* @param {String} obj.refreshToken - refresh token to use to get new access token for GitLab
* @returns
*/
const exchangeRefreshGitLab = async ({
refreshToken,
url
}: {
url?: string | null;
refreshToken: string;
}) => {
const exchangeRefreshGitLab = async ({ refreshToken, url }: { url?: string | null; refreshToken: string }) => {
const accessExpiresAt = new Date();
const appCfg = getConfig();
if (!appCfg.CLIENT_ID_GITLAB || !appCfg.CLIENT_SECRET_GITLAB) {
@@ -628,19 +622,18 @@ const exchangeRefreshGCPSecretManager = async ({
const token = jwt.sign(payload, serviceAccount.private_key, { algorithm: "RS256" });
const { data }: { data: ServiceAccountAccessTokenGCPSecretManagerResponse } =
await request.post(
IntegrationUrls.GCP_TOKEN_URL,
new URLSearchParams({
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
assertion: token
}).toString(),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
const { data }: { data: ServiceAccountAccessTokenGCPSecretManagerResponse } = await request.post(
IntegrationUrls.GCP_TOKEN_URL,
new URLSearchParams({
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
assertion: token
}).toString(),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
);
}
);
accessExpiresAt.setSeconds(accessExpiresAt.getSeconds() + data.expires_in);