feat: changed backend-pg to backend

This commit is contained in:
Akhil Mohan
2024-01-27 19:14:33 +05:30
parent d13eafcef7
commit 66d258f02b
792 changed files with 40298 additions and 40607 deletions
@@ -0,0 +1,195 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName, TIntegrations } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols } from "@app/lib/knex";
export type TIntegrationDALFactory = ReturnType<typeof integrationDALFactory>;
export const integrationDALFactory = (db: TDbClient) => {
const integrationOrm = ormify(db, TableName.Integration);
const integrationFindQuery = (tx: Knex, filter: Partial<TIntegrations>) =>
tx(TableName.Integration)
.where(filter)
.join(TableName.Environment, `${TableName.Integration}.envId`, `${TableName.Environment}.id`)
.select(tx.ref("name").withSchema(TableName.Environment).as("envName"))
.select(tx.ref("slug").withSchema(TableName.Environment).as("envSlug"))
.select(tx.ref("id").withSchema(TableName.Environment).as("envId"))
.select(tx.ref("projectId").withSchema(TableName.Environment))
.select(selectAllTableCols(TableName.Integration));
const find = async (filter: Partial<TIntegrations>, tx?: Knex) => {
try {
const docs = await integrationFindQuery(tx || db, filter);
return docs.map(({ envId, envSlug, envName, ...el }) => ({
...el,
environment: {
id: envId,
slug: envSlug,
name: envName
}
}));
} catch (error) {
throw new DatabaseError({ error, name: "Find by id integrations" });
}
};
const findOne = async (filter: Partial<TIntegrations>, tx?: Knex) => {
try {
const doc = await integrationFindQuery(tx || db, filter).first();
if (!doc) return;
const { envName: name, envSlug: slug, envId: id, ...el } = doc;
return { ...el, environment: { id, name, slug } };
} catch (error) {
throw new DatabaseError({ error, name: "Find one integrations" });
}
};
const findById = async (id: string, tx?: Knex) => {
try {
const doc = await integrationFindQuery(tx || db, {
[`${TableName.Integration}.id` as "id"]: id
}).first();
if (!doc) return;
const { envName: name, envSlug: slug, envId, ...el } = doc;
return { ...el, environment: { id: envId, name, slug } };
} catch (error) {
throw new DatabaseError({ error, name: "Find by id integrations" });
}
};
const findByProjectId = async (projectId: string, tx?: Knex) => {
try {
const integrations = await (tx || db)(TableName.Integration)
.where(`${TableName.Environment}.projectId`, projectId)
.join(
TableName.Environment,
`${TableName.Integration}.envId`,
`${TableName.Environment}.id`
)
.select(db.ref("name").withSchema(TableName.Environment).as("envName"))
.select(db.ref("slug").withSchema(TableName.Environment).as("envSlug"))
.select(db.ref("id").withSchema(TableName.Environment).as("envId"))
.select(db.ref("projectId").withSchema(TableName.Environment))
.select(selectAllTableCols(TableName.Integration));
return integrations.map(({ envId, envSlug, envName, ...el }) => ({
...el,
envId,
environment: {
id: envId,
slug: envSlug,
name: envName
}
}));
} catch (error) {
throw new DatabaseError({ error, name: "FindByProjectId" });
}
};
// used for syncing secrets
// this will populate integration auth also
const findByProjectIdV2 = async (projectId: string, environment: string, tx?: Knex) => {
const docs = await (tx || db)(TableName.Integration)
.where(`${TableName.Environment}.projectId`, projectId)
.where("isActive", true)
.where(`${TableName.Environment}.slug`, environment)
.join(TableName.Environment, `${TableName.Integration}.envId`, `${TableName.Environment}.id`)
.join(
TableName.IntegrationAuth,
`${TableName.IntegrationAuth}.id`,
`${TableName.Integration}.integrationAuthId`
)
.select(db.ref("name").withSchema(TableName.Environment).as("envName"))
.select(db.ref("slug").withSchema(TableName.Environment).as("envSlug"))
.select(db.ref("id").withSchema(TableName.Environment).as("envId"))
.select(db.ref("projectId").withSchema(TableName.Environment))
.select(selectAllTableCols(TableName.Integration))
.select(
db.ref("id").withSchema(TableName.IntegrationAuth).as("idAu"),
db.ref("integration").withSchema(TableName.IntegrationAuth).as("integrationAu"),
db.ref("teamId").withSchema(TableName.IntegrationAuth).as("teamIdAu"),
db.ref("url").withSchema(TableName.IntegrationAuth).as("urlAu"),
db.ref("namespace").withSchema(TableName.IntegrationAuth).as("namespaceAu"),
db.ref("accountId").withSchema(TableName.IntegrationAuth).as("accountIdAu"),
db.ref("refreshCiphertext").withSchema(TableName.IntegrationAuth).as("refreshCiphertextAu"),
db.ref("refreshIV").withSchema(TableName.IntegrationAuth).as("refreshIVAu"),
db.ref("refreshTag").withSchema(TableName.IntegrationAuth).as("refreshTagAu"),
db
.ref("accessIdCiphertext")
.withSchema(TableName.IntegrationAuth)
.as("accessIdCiphertextAu"),
db.ref("accessIdIV").withSchema(TableName.IntegrationAuth).as("accessIdIVAu"),
db.ref("accessIdTag").withSchema(TableName.IntegrationAuth).as("accessIdTagAu"),
db.ref("accessIV").withSchema(TableName.IntegrationAuth).as("accessIVAu"),
db.ref("accessTag").withSchema(TableName.IntegrationAuth).as("accessTagAu"),
db.ref("accessCiphertext").withSchema(TableName.IntegrationAuth).as("accessCiphertextAu"),
db.ref("accessExpiresAt").withSchema(TableName.IntegrationAuth).as("accessExpiresAtAu"),
db.ref("metadata").withSchema(TableName.IntegrationAuth).as("metadataAu"),
db.ref("algorithm").withSchema(TableName.IntegrationAuth).as("algorithmAu"),
db.ref("keyEncoding").withSchema(TableName.IntegrationAuth).as("keyEncodingAu")
);
return docs.map(
({
envId,
envName,
envSlug,
idAu: id,
integrationAu: integration,
teamIdAu: teamId,
urlAu: url,
namespaceAu: namespace,
accountIdAu: accountId,
refreshIVAu: refreshIV,
refreshCiphertextAu: refreshCiphertext,
refreshTagAu: refreshTag,
accessIVAu: accessIV,
accessCiphertextAu: accessCiphertext,
accessTagAu: accessTag,
accessIdIVAu: accessIdIV,
accessIdTagAu: accessIdTag,
accessIdCiphertextAu: accessIdCiphertext,
metadataAu: metadata,
algorithmAu: algorithm,
keyEncodingAu: keyEncoding,
accessExpiresAtAu: accessExpiresAt,
...el
}) => ({
...el,
envId,
environment: {
id: envId,
name: envName,
slug: envSlug
},
integrationAuth: {
id,
integration,
teamId,
url,
namespace,
accountId,
refreshTag,
refreshIV,
refreshCiphertext,
accessIdCiphertext,
accessIdIV,
accessIdTag,
accessIV,
accessCiphertext,
accessTag,
metadata,
algorithm,
keyEncoding,
accessExpiresAt
}
})
);
};
return { ...integrationOrm, find, findOne, findById, findByProjectId, findByProjectIdV2 };
};
@@ -0,0 +1,180 @@
import { ForbiddenError } from "@casl/ability";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import {
ProjectPermissionActions,
ProjectPermissionSub
} from "@app/ee/services/permission/project-permission";
import { BadRequestError } from "@app/lib/errors";
import { TProjectPermission } from "@app/lib/types";
import { TIntegrationAuthDALFactory } from "../integration-auth/integration-auth-dal";
import { TSecretQueueFactory } from "../secret/secret-queue";
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
import { TIntegrationDALFactory } from "./integration-dal";
import {
TCreateIntegrationDTO,
TDeleteIntegrationDTO,
TUpdateIntegrationDTO
} from "./integration-types";
type TIntegrationServiceFactoryDep = {
integrationDAL: TIntegrationDALFactory;
integrationAuthDAL: TIntegrationAuthDALFactory;
folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
secretQueueService: Pick<TSecretQueueFactory, "syncIntegrations">;
};
export type TIntegrationServiceFactory = ReturnType<typeof integrationServiceFactory>;
export const integrationServiceFactory = ({
integrationDAL,
integrationAuthDAL,
folderDAL,
permissionService,
secretQueueService
}: TIntegrationServiceFactoryDep) => {
const createIntegration = async ({
app,
actor,
path,
appId,
owner,
scope,
actorId,
region,
isActive,
metadata,
secretPath,
targetService,
targetServiceId,
integrationAuthId,
sourceEnvironment,
targetEnvironment,
targetEnvironmentId
}: TCreateIntegrationDTO) => {
const integrationAuth = await integrationAuthDAL.findById(integrationAuthId);
if (!integrationAuth) throw new BadRequestError({ message: "Integration auth not found" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integrationAuth.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create,
ProjectPermissionSub.Integrations
);
const folder = await folderDAL.findBySecretPath(
integrationAuth.projectId,
sourceEnvironment,
secretPath
);
if (!folder) throw new BadRequestError({ message: "Folder path not found" });
const integration = await integrationDAL.create({
envId: folder.envId,
secretPath,
isActive,
integrationAuthId,
targetEnvironmentId,
targetEnvironment,
targetServiceId,
targetService,
metadata,
region,
scope,
owner,
appId,
path,
app,
integration: integrationAuth.integration
});
await secretQueueService.syncIntegrations({
environment: sourceEnvironment,
secretPath,
projectId: integrationAuth.projectId
});
return { integration, integrationAuth };
};
const updateIntegration = async ({
actorId,
actor,
targetEnvironment,
app,
id,
appId,
owner,
isActive,
environment,
secretPath
}: TUpdateIntegrationDTO) => {
const integration = await integrationDAL.findById(id);
if (!integration) throw new BadRequestError({ message: "Integration auth not found" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integration.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
ProjectPermissionSub.Integrations
);
const folder = await folderDAL.findBySecretPath(integration.projectId, environment, secretPath);
if (!folder) throw new BadRequestError({ message: "Folder path not found" });
const updatedIntegration = await integrationDAL.updateById(id, {
envId: folder.envId,
isActive,
app,
appId,
targetEnvironment,
owner,
secretPath
});
return updatedIntegration;
};
const deleteIntegration = async ({ actorId, id, actor }: TDeleteIntegrationDTO) => {
const integration = await integrationDAL.findById(id);
if (!integration) throw new BadRequestError({ message: "Integration auth not found" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
integration.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete,
ProjectPermissionSub.Integrations
);
const deletedIntegration = await integrationDAL.deleteById(id);
return { ...integration, ...deletedIntegration };
};
const listIntegrationByProject = async ({ actor, actorId, projectId }: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Integrations
);
const integrations = await integrationDAL.findByProjectId(projectId);
return integrations;
};
return {
createIntegration,
updateIntegration,
deleteIntegration,
listIntegrationByProject
};
};
@@ -0,0 +1,41 @@
import { TProjectPermission } from "@app/lib/types";
export type TCreateIntegrationDTO = {
secretPath: string;
integrationAuthId: string;
app?: string;
isActive: boolean;
appId?: string;
sourceEnvironment: string;
targetEnvironment?: string;
targetEnvironmentId?: string;
targetService?: string;
targetServiceId?: string;
owner?: string;
path?: string;
region?: string;
scope?: string;
metadata?: {
secretPrefix?: string;
secretSuffix?: string;
secretGCPLabel?: {
labelName: string;
labelValue: string;
};
};
} & Omit<TProjectPermission, "projectId">;
export type TUpdateIntegrationDTO = {
id: string;
app: string;
appId: string;
isActive?: boolean;
secretPath: string;
targetEnvironment: string;
owner: string;
environment: string;
} & Omit<TProjectPermission, "projectId">;
export type TDeleteIntegrationDTO = {
id: string;
} & Omit<TProjectPermission, "projectId">;