diff --git a/backend/src/@types/fastify.d.ts b/backend/src/@types/fastify.d.ts index 325da75e1..5c05e3f14 100644 --- a/backend/src/@types/fastify.d.ts +++ b/backend/src/@types/fastify.d.ts @@ -3,13 +3,12 @@ import "fastify"; import { Redis } from "ioredis"; import { TUsers } from "@app/db/schemas"; -import { TAccessApprovalPolicyServiceFactory } from "@app/ee/services/access-approval-policy/access-approval-policy-service"; -import { TAccessApprovalRequestServiceFactory } from "@app/ee/services/access-approval-request/access-approval-request-service"; -import { TAssumePrivilegeServiceFactory } from "@app/ee/services/assume-privilege/assume-privilege-service"; -import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service"; -import { TCreateAuditLogDTO } from "@app/ee/services/audit-log/audit-log-types"; -import { TAuditLogStreamServiceFactory } from "@app/ee/services/audit-log-stream/audit-log-stream-service"; -import { TCertificateAuthorityCrlServiceFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-service"; +import { TAccessApprovalPolicyServiceFactory } from "@app/ee/services/access-approval-policy/access-approval-policy-types"; +import { TAccessApprovalRequestServiceFactory } from "@app/ee/services/access-approval-request/access-approval-request-types"; +import { TAssumePrivilegeServiceFactory } from "@app/ee/services/assume-privilege/assume-privilege-types"; +import { TAuditLogServiceFactory, TCreateAuditLogDTO } from "@app/ee/services/audit-log/audit-log-types"; +import { TAuditLogStreamServiceFactory } from "@app/ee/services/audit-log-stream/audit-log-stream-types"; +import { TCertificateAuthorityCrlServiceFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-types"; import { TCertificateEstServiceFactory } from "@app/ee/services/certificate-est/certificate-est-service"; import { TDynamicSecretServiceFactory } from "@app/ee/services/dynamic-secret/dynamic-secret-service"; import { TDynamicSecretLeaseServiceFactory } from "@app/ee/services/dynamic-secret-lease/dynamic-secret-lease-service"; @@ -25,14 +24,13 @@ import { TKmipServiceFactory } from "@app/ee/services/kmip/kmip-service"; import { TLdapConfigServiceFactory } from "@app/ee/services/ldap-config/ldap-config-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TOidcConfigServiceFactory } from "@app/ee/services/oidc/oidc-config-service"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { TPitServiceFactory } from "@app/ee/services/pit/pit-service"; -import { TProjectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-service"; -import { TProjectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-service"; -import { TRateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-service"; -import { RateLimitConfiguration } from "@app/ee/services/rate-limit/rate-limit-types"; -import { TSamlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-service"; -import { TScimServiceFactory } from "@app/ee/services/scim/scim-service"; +import { TProjectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-types"; +import { TProjectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-types"; +import { RateLimitConfiguration, TRateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-types"; +import { TSamlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-types"; +import { TScimServiceFactory } from "@app/ee/services/scim/scim-types"; import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service"; import { TSecretApprovalRequestServiceFactory } from "@app/ee/services/secret-approval-request/secret-approval-request-service"; import { TSecretRotationServiceFactory } from "@app/ee/services/secret-rotation/secret-rotation-service"; @@ -44,7 +42,7 @@ import { TSshCertificateAuthorityServiceFactory } from "@app/ee/services/ssh/ssh import { TSshCertificateTemplateServiceFactory } from "@app/ee/services/ssh-certificate-template/ssh-certificate-template-service"; import { TSshHostServiceFactory } from "@app/ee/services/ssh-host/ssh-host-service"; import { TSshHostGroupServiceFactory } from "@app/ee/services/ssh-host-group/ssh-host-group-service"; -import { TTrustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-service"; +import { TTrustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-types"; import { TAuthMode } from "@app/server/plugins/auth/inject-identity"; import { TApiKeyServiceFactory } from "@app/services/api-key/api-key-service"; import { TAppConnectionServiceFactory } from "@app/services/app-connection/app-connection-service"; diff --git a/backend/src/db/instance.ts b/backend/src/db/instance.ts index 5a8dd3d05..cdb8c3028 100644 --- a/backend/src/db/instance.ts +++ b/backend/src/db/instance.ts @@ -1,6 +1,6 @@ import knex, { Knex } from "knex"; -export type TDbClient = ReturnType; +export type TDbClient = Knex; export const initDbConnection = ({ dbConnectionUri, dbRootCert, diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-approver-dal.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-approver-dal.ts index c141c762b..ee7157e72 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-approver-dal.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-approver-dal.ts @@ -1,15 +1,15 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TAccessApprovalPolicyApproverDALFactory = ReturnType; +export type TAccessApprovalPolicyApproverDALFactory = TOrmify; export const accessApprovalPolicyApproverDALFactory = (db: TDbClient) => { const accessApprovalPolicyApproverOrm = ormify(db, TableName.AccessApprovalPolicyApprover); return { ...accessApprovalPolicyApproverOrm }; }; -export type TAccessApprovalPolicyBypasserDALFactory = ReturnType; +export type TAccessApprovalPolicyBypasserDALFactory = TOrmify; export const accessApprovalPolicyBypasserDALFactory = (db: TDbClient) => { const accessApprovalPolicyBypasserOrm = ormify(db, TableName.AccessApprovalPolicyBypasser); diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts index dbcc5ed14..9fa48ca15 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-dal.ts @@ -3,13 +3,363 @@ import { Knex } from "knex"; import { TDbClient } from "@app/db"; import { AccessApprovalPoliciesSchema, TableName, TAccessApprovalPolicies, TUsers } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; -import { buildFindFilter, ormify, selectAllTableCols, sqlNestRelationships, TFindFilter } from "@app/lib/knex"; +import { buildFindFilter, ormify, selectAllTableCols, sqlNestRelationships, TFindFilter, TOrmify } from "@app/lib/knex"; -import { ApproverType, BypasserType } from "./access-approval-policy-types"; +import { + ApproverType, + BypasserType, + TCreateAccessApprovalPolicy, + TDeleteAccessApprovalPolicy, + TGetAccessApprovalPolicyByIdDTO, + TGetAccessPolicyCountByEnvironmentDTO, + TListAccessApprovalPoliciesDTO, + TUpdateAccessApprovalPolicy +} from "./access-approval-policy-types"; -export type TAccessApprovalPolicyDALFactory = ReturnType; +export interface TAccessApprovalPolicyDALFactory + extends Omit, "findById" | "find"> { + find: ( + filter: TFindFilter< + TAccessApprovalPolicies & { + projectId: string; + } + >, + customFilter?: { + policyId?: string; + }, + tx?: Knex + ) => Promise< + { + approvers: ( + | { + id: string | null | undefined; + type: ApproverType.User; + name: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + | { + id: string | null | undefined; + type: ApproverType.Group; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + )[]; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + bypassers: ( + | { + id: string | null | undefined; + type: BypasserType.User; + name: string; + } + | { + id: string | null | undefined; + type: BypasserType.Group; + } + )[]; + }[] + >; + findById: ( + policyId: string, + tx?: Knex + ) => Promise< + | { + approvers: { + id: string | null | undefined; + type: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + }[]; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + } + | undefined + >; + softDeleteById: ( + policyId: string, + tx?: Knex + ) => Promise<{ + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + }>; + findLastValidPolicy: ( + { + envId, + secretPath + }: { + envId: string; + secretPath: string; + }, + tx?: Knex + ) => Promise< + | { + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + } + | undefined + >; +} -export const accessApprovalPolicyDALFactory = (db: TDbClient) => { +export interface TAccessApprovalPolicyServiceFactory { + getAccessPolicyCountByEnvSlug: ({ + actor, + actorOrgId, + actorAuthMethod, + projectSlug, + actorId, + envSlug + }: TGetAccessPolicyCountByEnvironmentDTO) => Promise<{ + count: number; + }>; + createAccessApprovalPolicy: ({ + name, + actor, + actorId, + actorOrgId, + secretPath, + actorAuthMethod, + approvals, + approvers, + bypassers, + projectSlug, + environment, + enforcementLevel, + allowedSelfApprovals, + approvalsRequired + }: TCreateAccessApprovalPolicy) => Promise<{ + environment: { + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + projectId: string; + slug: string; + position: number; + }; + projectId: string; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + }>; + deleteAccessApprovalPolicy: ({ + policyId, + actor, + actorId, + actorAuthMethod, + actorOrgId + }: TDeleteAccessApprovalPolicy) => Promise<{ + approvers: { + id: string | null | undefined; + type: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + }[]; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + }>; + updateAccessApprovalPolicy: ({ + policyId, + approvers, + bypassers, + secretPath, + name, + actorId, + actor, + actorOrgId, + actorAuthMethod, + approvals, + enforcementLevel, + allowedSelfApprovals, + approvalsRequired + }: TUpdateAccessApprovalPolicy) => Promise<{ + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + }>; + getAccessApprovalPolicyByProjectSlug: ({ + actorId, + actor, + actorOrgId, + actorAuthMethod, + projectSlug + }: TListAccessApprovalPoliciesDTO) => Promise< + { + approvers: ( + | { + id: string | null | undefined; + type: ApproverType; + name: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + | { + id: string | null | undefined; + type: ApproverType; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + )[]; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + bypassers: ( + | { + id: string | null | undefined; + type: BypasserType; + name: string; + } + | { + id: string | null | undefined; + type: BypasserType; + } + )[]; + }[] + >; + getAccessApprovalPolicyById: ({ + actorId, + actor, + actorOrgId, + actorAuthMethod, + policyId + }: TGetAccessApprovalPolicyByIdDTO) => Promise<{ + approvers: ( + | { + id: string | null | undefined; + type: ApproverType.User; + name: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + | { + id: string | null | undefined; + type: ApproverType.Group; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + )[]; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + bypassers: ( + | { + id: string | null | undefined; + type: BypasserType.User; + name: string; + } + | { + id: string | null | undefined; + type: BypasserType.Group; + } + )[]; + }>; +} + +export const accessApprovalPolicyDALFactory = (db: TDbClient): TAccessApprovalPolicyDALFactory => { const accessApprovalPolicyOrm = ormify(db, TableName.AccessApprovalPolicy); const accessApprovalPolicyFindQuery = async ( @@ -61,7 +411,7 @@ export const accessApprovalPolicyDALFactory = (db: TDbClient) => { return result; }; - const findById = async (policyId: string, tx?: Knex) => { + const findById: TAccessApprovalPolicyDALFactory["findById"] = async (policyId, tx) => { try { const doc = await accessApprovalPolicyFindQuery(tx || db.replicaNode(), { [`${TableName.AccessApprovalPolicy}.id` as "id"]: policyId @@ -112,13 +462,7 @@ export const accessApprovalPolicyDALFactory = (db: TDbClient) => { } }; - const find = async ( - filter: TFindFilter, - customFilter?: { - policyId?: string; - }, - tx?: Knex - ) => { + const find: TAccessApprovalPolicyDALFactory["find"] = async (filter, customFilter, tx) => { try { const docs = await accessApprovalPolicyFindQuery(tx || db.replicaNode(), filter, customFilter); @@ -141,7 +485,7 @@ export const accessApprovalPolicyDALFactory = (db: TDbClient) => { label: "approvers" as const, mapper: ({ approverUserId: id, approverUsername, approverSequence, approvalsRequired }) => ({ id, - type: ApproverType.User, + type: ApproverType.User as const, name: approverUsername, sequence: approverSequence, approvalsRequired @@ -152,7 +496,7 @@ export const accessApprovalPolicyDALFactory = (db: TDbClient) => { label: "approvers" as const, mapper: ({ approverGroupId: id, approverSequence, approvalsRequired }) => ({ id, - type: ApproverType.Group, + type: ApproverType.Group as const, sequence: approverSequence, approvalsRequired }) @@ -162,7 +506,7 @@ export const accessApprovalPolicyDALFactory = (db: TDbClient) => { label: "bypassers" as const, mapper: ({ bypasserUserId: id, bypasserUsername }) => ({ id, - type: BypasserType.User, + type: BypasserType.User as const, name: bypasserUsername }) }, @@ -171,7 +515,7 @@ export const accessApprovalPolicyDALFactory = (db: TDbClient) => { label: "bypassers" as const, mapper: ({ bypasserGroupId: id }) => ({ id, - type: BypasserType.Group + type: BypasserType.Group as const }) } ] @@ -186,12 +530,15 @@ export const accessApprovalPolicyDALFactory = (db: TDbClient) => { } }; - const softDeleteById = async (policyId: string, tx?: Knex) => { + const softDeleteById: TAccessApprovalPolicyDALFactory["softDeleteById"] = async (policyId, tx) => { const softDeletedPolicy = await accessApprovalPolicyOrm.updateById(policyId, { deletedAt: new Date() }, tx); return softDeletedPolicy; }; - const findLastValidPolicy = async ({ envId, secretPath }: { envId: string; secretPath: string }, tx?: Knex) => { + const findLastValidPolicy: TAccessApprovalPolicyDALFactory["findLastValidPolicy"] = async ( + { envId, secretPath }, + tx + ) => { try { const result = await (tx || db.replicaNode())(TableName.AccessApprovalPolicy) .where( diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts index 7ff9d65cc..4e818df2a 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { groupBy } from "@app/lib/fn"; @@ -24,9 +24,8 @@ import { TAccessApprovalPolicyDALFactory } from "./access-approval-policy-dal"; import { ApproverType, BypasserType, - TCreateAccessApprovalPolicy, + TAccessApprovalPolicyServiceFactory, TDeleteAccessApprovalPolicy, - TGetAccessApprovalPolicyByIdDTO, TGetAccessPolicyCountByEnvironmentDTO, TListAccessApprovalPoliciesDTO, TUpdateAccessApprovalPolicy @@ -48,8 +47,6 @@ type TAccessApprovalPolicyServiceFactoryDep = { orgMembershipDAL: Pick; }; -export type TAccessApprovalPolicyServiceFactory = ReturnType; - export const accessApprovalPolicyServiceFactory = ({ accessApprovalPolicyDAL, accessApprovalPolicyApproverDAL, @@ -63,8 +60,8 @@ export const accessApprovalPolicyServiceFactory = ({ additionalPrivilegeDAL, accessApprovalRequestReviewerDAL, orgMembershipDAL -}: TAccessApprovalPolicyServiceFactoryDep) => { - const createAccessApprovalPolicy = async ({ +}: TAccessApprovalPolicyServiceFactoryDep): TAccessApprovalPolicyServiceFactory => { + const createAccessApprovalPolicy: TAccessApprovalPolicyServiceFactory["createAccessApprovalPolicy"] = async ({ name, actor, actorId, @@ -79,7 +76,7 @@ export const accessApprovalPolicyServiceFactory = ({ enforcementLevel, allowedSelfApprovals, approvalsRequired - }: TCreateAccessApprovalPolicy) => { + }) => { const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` }); @@ -240,31 +237,26 @@ export const accessApprovalPolicyServiceFactory = ({ return { ...accessApproval, environment: env, projectId: project.id }; }; - const getAccessApprovalPolicyByProjectSlug = async ({ - actorId, - actor, - actorOrgId, - actorAuthMethod, - projectSlug - }: TListAccessApprovalPoliciesDTO) => { - const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); - if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` }); + const getAccessApprovalPolicyByProjectSlug: TAccessApprovalPolicyServiceFactory["getAccessApprovalPolicyByProjectSlug"] = + async ({ actorId, actor, actorOrgId, actorAuthMethod, projectSlug }: TListAccessApprovalPoliciesDTO) => { + const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); + if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` }); - // Anyone in the project should be able to get the policies. - await permissionService.getProjectPermission({ - actor, - actorId, - projectId: project.id, - actorAuthMethod, - actorOrgId, - actionProjectType: ActionProjectType.SecretManager - }); + // Anyone in the project should be able to get the policies. + await permissionService.getProjectPermission({ + actor, + actorId, + projectId: project.id, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.SecretManager + }); - const accessApprovalPolicies = await accessApprovalPolicyDAL.find({ projectId: project.id, deletedAt: null }); - return accessApprovalPolicies; - }; + const accessApprovalPolicies = await accessApprovalPolicyDAL.find({ projectId: project.id, deletedAt: null }); + return accessApprovalPolicies; + }; - const updateAccessApprovalPolicy = async ({ + const updateAccessApprovalPolicy: TAccessApprovalPolicyServiceFactory["updateAccessApprovalPolicy"] = async ({ policyId, approvers, bypassers, @@ -483,6 +475,7 @@ export const accessApprovalPolicyServiceFactory = ({ return doc; }); + return { ...updatedPolicy, environment: accessApprovalPolicy.environment, @@ -490,7 +483,7 @@ export const accessApprovalPolicyServiceFactory = ({ }; }; - const deleteAccessApprovalPolicy = async ({ + const deleteAccessApprovalPolicy: TAccessApprovalPolicyServiceFactory["deleteAccessApprovalPolicy"] = async ({ policyId, actor, actorId, @@ -539,7 +532,7 @@ export const accessApprovalPolicyServiceFactory = ({ return policy; }; - const getAccessPolicyCountByEnvSlug = async ({ + const getAccessPolicyCountByEnvSlug: TAccessApprovalPolicyServiceFactory["getAccessPolicyCountByEnvSlug"] = async ({ actor, actorOrgId, actorAuthMethod, @@ -576,13 +569,13 @@ export const accessApprovalPolicyServiceFactory = ({ return { count: policies.length }; }; - const getAccessApprovalPolicyById = async ({ + const getAccessApprovalPolicyById: TAccessApprovalPolicyServiceFactory["getAccessApprovalPolicyById"] = async ({ actorId, actor, actorOrgId, actorAuthMethod, policyId - }: TGetAccessApprovalPolicyByIdDTO) => { + }) => { const [policy] = await accessApprovalPolicyDAL.find({}, { policyId }); if (!policy) { diff --git a/backend/src/ee/services/access-approval-policy/access-approval-policy-types.ts b/backend/src/ee/services/access-approval-policy/access-approval-policy-types.ts index bdb50dde1..6806c7123 100644 --- a/backend/src/ee/services/access-approval-policy/access-approval-policy-types.ts +++ b/backend/src/ee/services/access-approval-policy/access-approval-policy-types.ts @@ -1,7 +1,7 @@ import { EnforcementLevel, TProjectPermission } from "@app/lib/types"; import { ActorAuthMethod } from "@app/services/auth/auth-type"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; export type TIsApproversValid = { userIds: string[]; @@ -76,3 +76,217 @@ export type TGetAccessApprovalPolicyByIdDTO = { export type TListAccessApprovalPoliciesDTO = { projectSlug: string; } & Omit; + +export interface TAccessApprovalPolicyServiceFactory { + getAccessPolicyCountByEnvSlug: ({ + actor, + actorOrgId, + actorAuthMethod, + projectSlug, + actorId, + envSlug + }: TGetAccessPolicyCountByEnvironmentDTO) => Promise<{ + count: number; + }>; + createAccessApprovalPolicy: ({ + name, + actor, + actorId, + actorOrgId, + secretPath, + actorAuthMethod, + approvals, + approvers, + bypassers, + projectSlug, + environment, + enforcementLevel, + allowedSelfApprovals, + approvalsRequired + }: TCreateAccessApprovalPolicy) => Promise<{ + environment: { + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + projectId: string; + slug: string; + position: number; + }; + projectId: string; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + }>; + deleteAccessApprovalPolicy: ({ + policyId, + actor, + actorId, + actorAuthMethod, + actorOrgId + }: TDeleteAccessApprovalPolicy) => Promise<{ + approvers: { + id: string | null | undefined; + type: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + }[]; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + }>; + updateAccessApprovalPolicy: ({ + policyId, + approvers, + bypassers, + secretPath, + name, + actorId, + actor, + actorOrgId, + actorAuthMethod, + approvals, + enforcementLevel, + allowedSelfApprovals, + approvalsRequired + }: TUpdateAccessApprovalPolicy) => Promise<{ + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + }>; + getAccessApprovalPolicyByProjectSlug: ({ + actorId, + actor, + actorOrgId, + actorAuthMethod, + projectSlug + }: TListAccessApprovalPoliciesDTO) => Promise< + { + approvers: ( + | { + id: string | null | undefined; + type: ApproverType; + name: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + | { + id: string | null | undefined; + type: ApproverType; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + )[]; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + bypassers: ( + | { + id: string | null | undefined; + type: BypasserType; + name: string; + } + | { + id: string | null | undefined; + type: BypasserType; + } + )[]; + }[] + >; + getAccessApprovalPolicyById: ({ + actorId, + actor, + actorOrgId, + actorAuthMethod, + policyId + }: TGetAccessApprovalPolicyByIdDTO) => Promise<{ + approvers: ( + | { + id: string | null | undefined; + type: ApproverType.User; + name: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + | { + id: string | null | undefined; + type: ApproverType.Group; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + )[]; + name: string; + id: string; + createdAt: Date; + updatedAt: Date; + approvals: number; + envId: string; + enforcementLevel: string; + allowedSelfApprovals: boolean; + secretPath?: string | null | undefined; + deletedAt?: Date | null | undefined; + environment: { + id: string; + name: string; + slug: string; + }; + projectId: string; + bypassers: ( + | { + id: string | null | undefined; + type: BypasserType.User; + name: string; + } + | { + id: string | null | undefined; + type: BypasserType.Group; + } + )[]; + }>; +} diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-dal.ts b/backend/src/ee/services/access-approval-request/access-approval-request-dal.ts index cb163f0c2..c69c55041 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-dal.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-dal.ts @@ -9,229 +9,442 @@ import { TUsers } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; -import { ormify, selectAllTableCols, sqlNestRelationships, TFindFilter } from "@app/lib/knex"; +import { ormify, selectAllTableCols, sqlNestRelationships, TFindFilter, TOrmify } from "@app/lib/knex"; import { ApprovalStatus } from "./access-approval-request-types"; -export type TAccessApprovalRequestDALFactory = ReturnType; +export interface TAccessApprovalRequestDALFactory extends Omit, "findById"> { + findById: ( + id: string, + tx?: Knex + ) => Promise< + | { + policy: { + approvers: ( + | { + userId: string | null | undefined; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + | { + userId: string; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + )[]; + bypassers: ( + | { + userId: string | null | undefined; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + } + | { + userId: string; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + } + )[]; + id: string; + name: string; + approvals: number; + secretPath: string | null | undefined; + enforcementLevel: string; + allowedSelfApprovals: boolean; + deletedAt: Date | null | undefined; + }; + projectId: string; + environment: string; + requestedByUser: { + userId: string; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + }; + status: string; + id: string; + createdAt: Date; + updatedAt: Date; + policyId: string; + isTemporary: boolean; + requestedByUserId: string; + privilegeId?: string | null | undefined; + requestedBy?: string | null | undefined; + temporaryRange?: string | null | undefined; + permissions?: unknown; + note?: string | null | undefined; + privilegeDeletedAt?: Date | null | undefined; + reviewers: { + userId: string; + status: string; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + }[]; + approvers: ( + | { + userId: string | null | undefined; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + | { + userId: string; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + } + )[]; + bypassers: ( + | { + userId: string | null | undefined; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + } + | { + userId: string; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + } + )[]; + } + | undefined + >; + findRequestsWithPrivilegeByPolicyIds: (policyIds: string[]) => Promise< + { + policy: { + approvers: ( + | { + userId: string | null | undefined; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + email: string | null | undefined; + username: string; + } + | { + userId: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + email: string | null | undefined; + username: string; + } + )[]; + bypassers: string[]; + id: string; + name: string; + approvals: number; + secretPath: string | null | undefined; + enforcementLevel: string; + allowedSelfApprovals: boolean; + envId: string; + deletedAt: Date | null | undefined; + }; + projectId: string; + environment: string; + environmentName: string; + requestedByUser: { + userId: string; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + }; + privilege: { + membershipId: string; + userId: string; + projectId: string; + isTemporary: boolean; + temporaryMode: string | null | undefined; + temporaryRange: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + permissions: unknown; + } | null; + isApproved: boolean; + status: string; + id: string; + createdAt: Date; + updatedAt: Date; + policyId: string; + isTemporary: boolean; + requestedByUserId: string; + privilegeId?: string | null | undefined; + requestedBy?: string | null | undefined; + temporaryRange?: string | null | undefined; + permissions?: unknown; + note?: string | null | undefined; + privilegeDeletedAt?: Date | null | undefined; + reviewers: { + userId: string; + status: string; + }[]; + approvers: ( + | { + userId: string | null | undefined; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + email: string | null | undefined; + username: string; + } + | { + userId: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + email: string | null | undefined; + username: string; + } + )[]; + bypassers: string[]; + }[] + >; + getCount: ({ projectId }: { projectId: string }) => Promise<{ + pendingCount: number; + finalizedCount: number; + }>; + resetReviewByPolicyId: (policyId: string, tx?: Knex) => Promise; +} -export const accessApprovalRequestDALFactory = (db: TDbClient) => { +export const accessApprovalRequestDALFactory = (db: TDbClient): TAccessApprovalRequestDALFactory => { const accessApprovalRequestOrm = ormify(db, TableName.AccessApprovalRequest); - const findRequestsWithPrivilegeByPolicyIds = async (policyIds: string[]) => { - try { - const docs = await db - .replicaNode()(TableName.AccessApprovalRequest) - .whereIn(`${TableName.AccessApprovalRequest}.policyId`, policyIds) + const findRequestsWithPrivilegeByPolicyIds: TAccessApprovalRequestDALFactory["findRequestsWithPrivilegeByPolicyIds"] = + async (policyIds) => { + try { + const docs = await db + .replicaNode()(TableName.AccessApprovalRequest) + .whereIn(`${TableName.AccessApprovalRequest}.policyId`, policyIds) - .leftJoin( - TableName.ProjectUserAdditionalPrivilege, - `${TableName.AccessApprovalRequest}.privilegeId`, - `${TableName.ProjectUserAdditionalPrivilege}.id` - ) - .leftJoin( - TableName.AccessApprovalPolicy, - `${TableName.AccessApprovalRequest}.policyId`, - `${TableName.AccessApprovalPolicy}.id` - ) - .leftJoin( - TableName.AccessApprovalRequestReviewer, - `${TableName.AccessApprovalRequest}.id`, - `${TableName.AccessApprovalRequestReviewer}.requestId` - ) - .leftJoin( - TableName.AccessApprovalPolicyApprover, - `${TableName.AccessApprovalPolicy}.id`, - `${TableName.AccessApprovalPolicyApprover}.policyId` - ) - .leftJoin( - db(TableName.Users).as("accessApprovalPolicyApproverUser"), - `${TableName.AccessApprovalPolicyApprover}.approverUserId`, - "accessApprovalPolicyApproverUser.id" - ) - .leftJoin( - TableName.UserGroupMembership, - `${TableName.AccessApprovalPolicyApprover}.approverGroupId`, - `${TableName.UserGroupMembership}.groupId` - ) - .leftJoin(TableName.Users, `${TableName.UserGroupMembership}.userId`, `${TableName.Users}.id`) + .leftJoin( + TableName.ProjectUserAdditionalPrivilege, + `${TableName.AccessApprovalRequest}.privilegeId`, + `${TableName.ProjectUserAdditionalPrivilege}.id` + ) + .leftJoin( + TableName.AccessApprovalPolicy, + `${TableName.AccessApprovalRequest}.policyId`, + `${TableName.AccessApprovalPolicy}.id` + ) + .leftJoin( + TableName.AccessApprovalRequestReviewer, + `${TableName.AccessApprovalRequest}.id`, + `${TableName.AccessApprovalRequestReviewer}.requestId` + ) + .leftJoin( + TableName.AccessApprovalPolicyApprover, + `${TableName.AccessApprovalPolicy}.id`, + `${TableName.AccessApprovalPolicyApprover}.policyId` + ) + .leftJoin( + db(TableName.Users).as("accessApprovalPolicyApproverUser"), + `${TableName.AccessApprovalPolicyApprover}.approverUserId`, + "accessApprovalPolicyApproverUser.id" + ) + .leftJoin( + TableName.UserGroupMembership, + `${TableName.AccessApprovalPolicyApprover}.approverGroupId`, + `${TableName.UserGroupMembership}.groupId` + ) + .leftJoin(TableName.Users, `${TableName.UserGroupMembership}.userId`, `${TableName.Users}.id`) - .leftJoin( - TableName.AccessApprovalPolicyBypasser, - `${TableName.AccessApprovalPolicy}.id`, - `${TableName.AccessApprovalPolicyBypasser}.policyId` - ) - .leftJoin( - db(TableName.UserGroupMembership).as("bypasserUserGroupMembership"), - `${TableName.AccessApprovalPolicyBypasser}.bypasserGroupId`, - `bypasserUserGroupMembership.groupId` - ) + .leftJoin( + TableName.AccessApprovalPolicyBypasser, + `${TableName.AccessApprovalPolicy}.id`, + `${TableName.AccessApprovalPolicyBypasser}.policyId` + ) + .leftJoin( + db(TableName.UserGroupMembership).as("bypasserUserGroupMembership"), + `${TableName.AccessApprovalPolicyBypasser}.bypasserGroupId`, + `bypasserUserGroupMembership.groupId` + ) - .join( - db(TableName.Users).as("requestedByUser"), - `${TableName.AccessApprovalRequest}.requestedByUserId`, - `requestedByUser.id` - ) + .join( + db(TableName.Users).as("requestedByUser"), + `${TableName.AccessApprovalRequest}.requestedByUserId`, + `requestedByUser.id` + ) - .leftJoin(TableName.Environment, `${TableName.AccessApprovalPolicy}.envId`, `${TableName.Environment}.id`) + .leftJoin(TableName.Environment, `${TableName.AccessApprovalPolicy}.envId`, `${TableName.Environment}.id`) - .select(selectAllTableCols(TableName.AccessApprovalRequest)) - .select( - db.ref("id").withSchema(TableName.AccessApprovalPolicy).as("policyId"), - db.ref("name").withSchema(TableName.AccessApprovalPolicy).as("policyName"), - db.ref("approvals").withSchema(TableName.AccessApprovalPolicy).as("policyApprovals"), - db.ref("secretPath").withSchema(TableName.AccessApprovalPolicy).as("policySecretPath"), - db.ref("enforcementLevel").withSchema(TableName.AccessApprovalPolicy).as("policyEnforcementLevel"), - db.ref("allowedSelfApprovals").withSchema(TableName.AccessApprovalPolicy).as("policyAllowedSelfApprovals"), - db.ref("envId").withSchema(TableName.AccessApprovalPolicy).as("policyEnvId"), - db.ref("deletedAt").withSchema(TableName.AccessApprovalPolicy).as("policyDeletedAt") - ) - .select(db.ref("approverUserId").withSchema(TableName.AccessApprovalPolicyApprover)) - .select(db.ref("sequence").withSchema(TableName.AccessApprovalPolicyApprover).as("approverSequence")) - .select(db.ref("approvalsRequired").withSchema(TableName.AccessApprovalPolicyApprover)) - .select(db.ref("userId").withSchema(TableName.UserGroupMembership).as("approverGroupUserId")) - .select(db.ref("bypasserUserId").withSchema(TableName.AccessApprovalPolicyBypasser)) - .select(db.ref("userId").withSchema("bypasserUserGroupMembership").as("bypasserGroupUserId")) - .select( - db.ref("email").withSchema("accessApprovalPolicyApproverUser").as("approverEmail"), - db.ref("email").withSchema(TableName.Users).as("approverGroupEmail"), - db.ref("username").withSchema("accessApprovalPolicyApproverUser").as("approverUsername"), - db.ref("username").withSchema(TableName.Users).as("approverGroupUsername") - ) - .select( - db.ref("projectId").withSchema(TableName.Environment), - db.ref("slug").withSchema(TableName.Environment).as("envSlug"), - db.ref("name").withSchema(TableName.Environment).as("envName") - ) + .select(selectAllTableCols(TableName.AccessApprovalRequest)) + .select( + db.ref("id").withSchema(TableName.AccessApprovalPolicy).as("policyId"), + db.ref("name").withSchema(TableName.AccessApprovalPolicy).as("policyName"), + db.ref("approvals").withSchema(TableName.AccessApprovalPolicy).as("policyApprovals"), + db.ref("secretPath").withSchema(TableName.AccessApprovalPolicy).as("policySecretPath"), + db.ref("enforcementLevel").withSchema(TableName.AccessApprovalPolicy).as("policyEnforcementLevel"), + db.ref("allowedSelfApprovals").withSchema(TableName.AccessApprovalPolicy).as("policyAllowedSelfApprovals"), + db.ref("envId").withSchema(TableName.AccessApprovalPolicy).as("policyEnvId"), + db.ref("deletedAt").withSchema(TableName.AccessApprovalPolicy).as("policyDeletedAt") + ) + .select(db.ref("approverUserId").withSchema(TableName.AccessApprovalPolicyApprover)) + .select(db.ref("sequence").withSchema(TableName.AccessApprovalPolicyApprover).as("approverSequence")) + .select(db.ref("approvalsRequired").withSchema(TableName.AccessApprovalPolicyApprover)) + .select(db.ref("userId").withSchema(TableName.UserGroupMembership).as("approverGroupUserId")) + .select(db.ref("bypasserUserId").withSchema(TableName.AccessApprovalPolicyBypasser)) + .select(db.ref("userId").withSchema("bypasserUserGroupMembership").as("bypasserGroupUserId")) + .select( + db.ref("email").withSchema("accessApprovalPolicyApproverUser").as("approverEmail"), + db.ref("email").withSchema(TableName.Users).as("approverGroupEmail"), + db.ref("username").withSchema("accessApprovalPolicyApproverUser").as("approverUsername"), + db.ref("username").withSchema(TableName.Users).as("approverGroupUsername") + ) + .select( + db.ref("projectId").withSchema(TableName.Environment), + db.ref("slug").withSchema(TableName.Environment).as("envSlug"), + db.ref("name").withSchema(TableName.Environment).as("envName") + ) - .select( - db.ref("reviewerUserId").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerUserId"), - db.ref("status").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerStatus") - ) + .select( + db.ref("reviewerUserId").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerUserId"), + db.ref("status").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerStatus") + ) - // TODO: ADD SUPPORT FOR GROUPS!!!! - .select( - db.ref("email").withSchema("requestedByUser").as("requestedByUserEmail"), - db.ref("username").withSchema("requestedByUser").as("requestedByUserUsername"), - db.ref("firstName").withSchema("requestedByUser").as("requestedByUserFirstName"), - db.ref("lastName").withSchema("requestedByUser").as("requestedByUserLastName"), + // TODO: ADD SUPPORT FOR GROUPS!!!! + .select( + db.ref("email").withSchema("requestedByUser").as("requestedByUserEmail"), + db.ref("username").withSchema("requestedByUser").as("requestedByUserUsername"), + db.ref("firstName").withSchema("requestedByUser").as("requestedByUserFirstName"), + db.ref("lastName").withSchema("requestedByUser").as("requestedByUserLastName"), - db.ref("userId").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeUserId"), - db.ref("projectId").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeMembershipId"), + db.ref("userId").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeUserId"), + db.ref("projectId").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeMembershipId"), - db.ref("isTemporary").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeIsTemporary"), - db.ref("temporaryMode").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeTemporaryMode"), - db.ref("temporaryRange").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeTemporaryRange"), - db - .ref("temporaryAccessStartTime") - .withSchema(TableName.ProjectUserAdditionalPrivilege) - .as("privilegeTemporaryAccessStartTime"), - db - .ref("temporaryAccessEndTime") - .withSchema(TableName.ProjectUserAdditionalPrivilege) - .as("privilegeTemporaryAccessEndTime"), + db.ref("isTemporary").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeIsTemporary"), + db.ref("temporaryMode").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeTemporaryMode"), + db.ref("temporaryRange").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeTemporaryRange"), + db + .ref("temporaryAccessStartTime") + .withSchema(TableName.ProjectUserAdditionalPrivilege) + .as("privilegeTemporaryAccessStartTime"), + db + .ref("temporaryAccessEndTime") + .withSchema(TableName.ProjectUserAdditionalPrivilege) + .as("privilegeTemporaryAccessEndTime"), - db.ref("permissions").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegePermissions") - ) - .orderBy(`${TableName.AccessApprovalRequest}.createdAt`, "desc"); + db.ref("permissions").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegePermissions") + ) + .orderBy(`${TableName.AccessApprovalRequest}.createdAt`, "desc"); - const formattedDocs = sqlNestRelationships({ - data: docs, - key: "id", - parentMapper: (doc) => ({ - ...AccessApprovalRequestsSchema.parse(doc), - projectId: doc.projectId, - environment: doc.envSlug, - environmentName: doc.envName, + const formattedDocs = sqlNestRelationships({ + data: docs, + key: "id", + parentMapper: (doc) => ({ + ...AccessApprovalRequestsSchema.parse(doc), + projectId: doc.projectId, + environment: doc.envSlug, + environmentName: doc.envName, + policy: { + id: doc.policyId, + name: doc.policyName, + approvals: doc.policyApprovals, + secretPath: doc.policySecretPath, + enforcementLevel: doc.policyEnforcementLevel, + allowedSelfApprovals: doc.policyAllowedSelfApprovals, + envId: doc.policyEnvId, + deletedAt: doc.policyDeletedAt + }, + requestedByUser: { + userId: doc.requestedByUserId, + email: doc.requestedByUserEmail, + firstName: doc.requestedByUserFirstName, + lastName: doc.requestedByUserLastName, + username: doc.requestedByUserUsername + }, + privilege: doc.privilegeId + ? { + membershipId: doc.privilegeMembershipId, + userId: doc.privilegeUserId, + projectId: doc.projectId, + isTemporary: doc.privilegeIsTemporary, + temporaryMode: doc.privilegeTemporaryMode, + temporaryRange: doc.privilegeTemporaryRange, + temporaryAccessStartTime: doc.privilegeTemporaryAccessStartTime, + temporaryAccessEndTime: doc.privilegeTemporaryAccessEndTime, + permissions: doc.privilegePermissions + } + : null, + isApproved: doc.status === ApprovalStatus.APPROVED + }), + childrenMapper: [ + { + key: "reviewerUserId", + label: "reviewers" as const, + mapper: ({ reviewerUserId: userId, reviewerStatus: status }) => (userId ? { userId, status } : undefined) + }, + { + key: "approverUserId", + label: "approvers" as const, + mapper: ({ approverUserId, approverSequence, approvalsRequired, approverUsername, approverEmail }) => ({ + userId: approverUserId, + sequence: approverSequence, + approvalsRequired, + email: approverEmail, + username: approverUsername + }) + }, + { + key: "approverGroupUserId", + label: "approvers" as const, + mapper: ({ + approverGroupUserId, + approverSequence, + approvalsRequired, + approverGroupEmail, + approverGroupUsername + }) => ({ + userId: approverGroupUserId, + sequence: approverSequence, + approvalsRequired, + email: approverGroupEmail, + username: approverGroupUsername + }) + }, + { key: "bypasserUserId", label: "bypassers" as const, mapper: ({ bypasserUserId }) => bypasserUserId }, + { + key: "bypasserGroupUserId", + label: "bypassers" as const, + mapper: ({ bypasserGroupUserId }) => bypasserGroupUserId + } + ] + }); + + if (!formattedDocs) return []; + + return formattedDocs.map((doc) => ({ + ...doc, policy: { - id: doc.policyId, - name: doc.policyName, - approvals: doc.policyApprovals, - secretPath: doc.policySecretPath, - enforcementLevel: doc.policyEnforcementLevel, - allowedSelfApprovals: doc.policyAllowedSelfApprovals, - envId: doc.policyEnvId, - deletedAt: doc.policyDeletedAt - }, - requestedByUser: { - userId: doc.requestedByUserId, - email: doc.requestedByUserEmail, - firstName: doc.requestedByUserFirstName, - lastName: doc.requestedByUserLastName, - username: doc.requestedByUserUsername - }, - privilege: doc.privilegeId - ? { - membershipId: doc.privilegeMembershipId, - userId: doc.privilegeUserId, - projectId: doc.projectId, - isTemporary: doc.privilegeIsTemporary, - temporaryMode: doc.privilegeTemporaryMode, - temporaryRange: doc.privilegeTemporaryRange, - temporaryAccessStartTime: doc.privilegeTemporaryAccessStartTime, - temporaryAccessEndTime: doc.privilegeTemporaryAccessEndTime, - permissions: doc.privilegePermissions - } - : null, - isApproved: doc.status === ApprovalStatus.APPROVED - }), - childrenMapper: [ - { - key: "reviewerUserId", - label: "reviewers" as const, - mapper: ({ reviewerUserId: userId, reviewerStatus: status }) => (userId ? { userId, status } : undefined) - }, - { - key: "approverUserId", - label: "approvers" as const, - mapper: ({ approverUserId, approverSequence, approvalsRequired, approverUsername, approverEmail }) => ({ - userId: approverUserId, - sequence: approverSequence, - approvalsRequired, - email: approverEmail, - username: approverUsername - }) - }, - { - key: "approverGroupUserId", - label: "approvers" as const, - mapper: ({ - approverGroupUserId, - approverSequence, - approvalsRequired, - approverGroupEmail, - approverGroupUsername - }) => ({ - userId: approverGroupUserId, - sequence: approverSequence, - approvalsRequired, - email: approverGroupEmail, - username: approverGroupUsername - }) - }, - { key: "bypasserUserId", label: "bypassers" as const, mapper: ({ bypasserUserId }) => bypasserUserId }, - { - key: "bypasserGroupUserId", - label: "bypassers" as const, - mapper: ({ bypasserGroupUserId }) => bypasserGroupUserId + ...doc.policy, + approvers: doc.approvers.filter((el) => el.userId).sort((a, b) => (a.sequence || 0) - (b.sequence || 0)), + bypassers: doc.bypassers } - ] - }); - - if (!formattedDocs) return []; - - return formattedDocs.map((doc) => ({ - ...doc, - policy: { - ...doc.policy, - approvers: doc.approvers.filter((el) => el.userId).sort((a, b) => (a.sequence || 0) - (b.sequence || 0)), - bypassers: doc.bypassers - } - })); - } catch (error) { - throw new DatabaseError({ error, name: "FindRequestsWithPrivilege" }); - } - }; + })); + } catch (error) { + throw new DatabaseError({ error, name: "FindRequestsWithPrivilege" }); + } + }; const findQuery = (filter: TFindFilter, tx: Knex) => tx(TableName.AccessApprovalRequest) @@ -354,7 +567,7 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => { tx.ref("deletedAt").withSchema(TableName.AccessApprovalPolicy).as("policyDeletedAt") ); - const findById = async (id: string, tx?: Knex) => { + const findById: TAccessApprovalRequestDALFactory["findById"] = async (id, tx) => { try { const sql = findQuery({ [`${TableName.AccessApprovalRequest}.id` as "id"]: id }, tx || db.replicaNode()); const docs = await sql; @@ -489,7 +702,7 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => { } }; - const getCount = async ({ projectId }: { projectId: string }) => { + const getCount: TAccessApprovalRequestDALFactory["getCount"] = async ({ projectId }) => { try { const accessRequests = await db .replicaNode()(TableName.AccessApprovalRequest) @@ -555,7 +768,7 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => { } }; - const resetReviewByPolicyId = async (policyId: string, tx?: Knex) => { + const resetReviewByPolicyId: TAccessApprovalRequestDALFactory["resetReviewByPolicyId"] = async (policyId, tx) => { try { await (tx || db)(TableName.AccessApprovalRequestReviewer) .leftJoin( diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-reviewer-dal.ts b/backend/src/ee/services/access-approval-request/access-approval-request-reviewer-dal.ts index 251015b22..0da53d168 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-reviewer-dal.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-reviewer-dal.ts @@ -1,10 +1,10 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TAccessApprovalRequestReviewerDALFactory = ReturnType; +export type TAccessApprovalRequestReviewerDALFactory = TOrmify; -export const accessApprovalRequestReviewerDALFactory = (db: TDbClient) => { +export const accessApprovalRequestReviewerDALFactory = (db: TDbClient): TAccessApprovalRequestReviewerDALFactory => { const secretApprovalRequestReviewerOrm = ormify(db, TableName.AccessApprovalRequestReviewer); return secretApprovalRequestReviewerOrm; }; diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts index 8fafc6b85..70d491bf0 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-service.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-service.ts @@ -23,19 +23,13 @@ import { TUserDALFactory } from "@app/services/user/user-dal"; import { TAccessApprovalPolicyApproverDALFactory } from "../access-approval-policy/access-approval-policy-approver-dal"; import { TAccessApprovalPolicyDALFactory } from "../access-approval-policy/access-approval-policy-dal"; import { TGroupDALFactory } from "../group/group-dal"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TProjectUserAdditionalPrivilegeDALFactory } from "../project-user-additional-privilege/project-user-additional-privilege-dal"; import { ProjectUserAdditionalPrivilegeTemporaryMode } from "../project-user-additional-privilege/project-user-additional-privilege-types"; import { TAccessApprovalRequestDALFactory } from "./access-approval-request-dal"; import { verifyRequestedPermissions } from "./access-approval-request-fns"; import { TAccessApprovalRequestReviewerDALFactory } from "./access-approval-request-reviewer-dal"; -import { - ApprovalStatus, - TCreateAccessApprovalRequestDTO, - TGetAccessRequestCountDTO, - TListApprovalRequestsDTO, - TReviewAccessRequestDTO -} from "./access-approval-request-types"; +import { ApprovalStatus, TAccessApprovalRequestServiceFactory } from "./access-approval-request-types"; type TSecretApprovalRequestServiceFactoryDep = { additionalPrivilegeDAL: Pick; @@ -75,8 +69,6 @@ type TSecretApprovalRequestServiceFactoryDep = { projectMicrosoftTeamsConfigDAL: Pick; }; -export type TAccessApprovalRequestServiceFactory = ReturnType; - export const accessApprovalRequestServiceFactory = ({ groupDAL, projectDAL, @@ -93,8 +85,8 @@ export const accessApprovalRequestServiceFactory = ({ microsoftTeamsService, projectMicrosoftTeamsConfigDAL, projectSlackConfigDAL -}: TSecretApprovalRequestServiceFactoryDep) => { - const createAccessApprovalRequest = async ({ +}: TSecretApprovalRequestServiceFactoryDep): TAccessApprovalRequestServiceFactory => { + const createAccessApprovalRequest: TAccessApprovalRequestServiceFactory["createAccessApprovalRequest"] = async ({ isTemporary, temporaryRange, actorId, @@ -104,7 +96,7 @@ export const accessApprovalRequestServiceFactory = ({ actorAuthMethod, projectSlug, note - }: TCreateAccessApprovalRequestDTO) => { + }) => { const cfg = getConfig(); const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` }); @@ -281,7 +273,7 @@ export const accessApprovalRequestServiceFactory = ({ return { request: approval }; }; - const listApprovalRequests = async ({ + const listApprovalRequests: TAccessApprovalRequestServiceFactory["listApprovalRequests"] = async ({ projectSlug, authorProjectMembershipId, envSlug, @@ -289,7 +281,7 @@ export const accessApprovalRequestServiceFactory = ({ actorOrgId, actorId, actorAuthMethod - }: TListApprovalRequestsDTO) => { + }) => { const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` }); @@ -319,7 +311,7 @@ export const accessApprovalRequestServiceFactory = ({ return { requests }; }; - const reviewAccessRequest = async ({ + const reviewAccessRequest: TAccessApprovalRequestServiceFactory["reviewAccessRequest"] = async ({ requestId, actor, status, @@ -327,7 +319,7 @@ export const accessApprovalRequestServiceFactory = ({ actorAuthMethod, actorOrgId, bypassReason - }: TReviewAccessRequestDTO) => { + }) => { const accessApprovalRequest = await accessApprovalRequestDAL.findById(requestId); if (!accessApprovalRequest) { throw new NotFoundError({ message: `Secret approval request with ID '${requestId}' not found` }); @@ -566,7 +558,13 @@ export const accessApprovalRequestServiceFactory = ({ return reviewStatus; }; - const getCount = async ({ projectSlug, actor, actorAuthMethod, actorId, actorOrgId }: TGetAccessRequestCountDTO) => { + const getCount: TAccessApprovalRequestServiceFactory["getCount"] = async ({ + projectSlug, + actor, + actorAuthMethod, + actorId, + actorOrgId + }) => { const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId); if (!project) throw new NotFoundError({ message: `Project with slug '${projectSlug}' not found` }); diff --git a/backend/src/ee/services/access-approval-request/access-approval-request-types.ts b/backend/src/ee/services/access-approval-request/access-approval-request-types.ts index 162f8b3c6..fb3e78de0 100644 --- a/backend/src/ee/services/access-approval-request/access-approval-request-types.ts +++ b/backend/src/ee/services/access-approval-request/access-approval-request-types.ts @@ -34,3 +34,124 @@ export type TListApprovalRequestsDTO = { authorProjectMembershipId?: string; envSlug?: string; } & Omit; + +export interface TAccessApprovalRequestServiceFactory { + createAccessApprovalRequest: (arg: TCreateAccessApprovalRequestDTO) => Promise<{ + request: { + status: string; + id: string; + createdAt: Date; + updatedAt: Date; + policyId: string; + isTemporary: boolean; + requestedByUserId: string; + privilegeId?: string | null | undefined; + requestedBy?: string | null | undefined; + temporaryRange?: string | null | undefined; + permissions?: unknown; + note?: string | null | undefined; + privilegeDeletedAt?: Date | null | undefined; + }; + }>; + listApprovalRequests: (arg: TListApprovalRequestsDTO) => Promise<{ + requests: { + policy: { + approvers: ( + | { + userId: string | null | undefined; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + email: string | null | undefined; + username: string; + } + | { + userId: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + email: string | null | undefined; + username: string; + } + )[]; + bypassers: string[]; + id: string; + name: string; + approvals: number; + secretPath: string | null | undefined; + enforcementLevel: string; + allowedSelfApprovals: boolean; + envId: string; + deletedAt: Date | null | undefined; + }; + projectId: string; + environment: string; + environmentName: string; + requestedByUser: { + userId: string; + email: string | null | undefined; + firstName: string | null | undefined; + lastName: string | null | undefined; + username: string; + }; + privilege: { + membershipId: string; + userId: string; + projectId: string; + isTemporary: boolean; + temporaryMode: string | null | undefined; + temporaryRange: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + permissions: unknown; + } | null; + isApproved: boolean; + status: string; + id: string; + createdAt: Date; + updatedAt: Date; + policyId: string; + isTemporary: boolean; + requestedByUserId: string; + privilegeId?: string | null | undefined; + requestedBy?: string | null | undefined; + temporaryRange?: string | null | undefined; + permissions?: unknown; + note?: string | null | undefined; + privilegeDeletedAt?: Date | null | undefined; + reviewers: { + userId: string; + status: string; + }[]; + approvers: ( + | { + userId: string | null | undefined; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + email: string | null | undefined; + username: string; + } + | { + userId: string; + sequence: number | null | undefined; + approvalsRequired: number | null | undefined; + email: string | null | undefined; + username: string; + } + )[]; + bypassers: string[]; + }[]; + }>; + reviewAccessRequest: (arg: TReviewAccessRequestDTO) => Promise<{ + id: string; + requestId: string; + reviewerUserId: string; + status: string; + createdAt: Date; + updatedAt: Date; + }>; + getCount: (arg: TGetAccessRequestCountDTO) => Promise<{ + count: { + pendingCount: number; + finalizedCount: number; + }; + }>; +} diff --git a/backend/src/ee/services/assume-privilege/assume-privilege-service.ts b/backend/src/ee/services/assume-privilege/assume-privilege-service.ts index 709ce44b6..d4a643d8b 100644 --- a/backend/src/ee/services/assume-privilege/assume-privilege-service.ts +++ b/backend/src/ee/services/assume-privilege/assume-privilege-service.ts @@ -7,29 +7,30 @@ import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { ActorType } from "@app/services/auth/auth-type"; import { TProjectDALFactory } from "@app/services/project/project-dal"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionIdentityActions, ProjectPermissionMemberActions, ProjectPermissionSub } from "../permission/project-permission"; -import { TAssumeProjectPrivilegeDTO } from "./assume-privilege-types"; +import { TAssumePrivilegeServiceFactory } from "./assume-privilege-types"; type TAssumePrivilegeServiceFactoryDep = { projectDAL: Pick; permissionService: Pick; }; -export type TAssumePrivilegeServiceFactory = ReturnType; - -export const assumePrivilegeServiceFactory = ({ projectDAL, permissionService }: TAssumePrivilegeServiceFactoryDep) => { - const assumeProjectPrivileges = async ({ +export const assumePrivilegeServiceFactory = ({ + projectDAL, + permissionService +}: TAssumePrivilegeServiceFactoryDep): TAssumePrivilegeServiceFactory => { + const assumeProjectPrivileges: TAssumePrivilegeServiceFactory["assumeProjectPrivileges"] = async ({ targetActorType, targetActorId, projectId, actorPermissionDetails, tokenVersionId - }: TAssumeProjectPrivilegeDTO) => { + }) => { const project = await projectDAL.findById(projectId); if (!project) throw new NotFoundError({ message: `Project with ID '${projectId}' not found` }); const { permission } = await permissionService.getProjectPermission({ @@ -79,7 +80,10 @@ export const assumePrivilegeServiceFactory = ({ projectDAL, permissionService }: return { actorType: targetActorType, actorId: targetActorId, projectId, assumePrivilegesToken }; }; - const verifyAssumePrivilegeToken = (token: string, tokenVersionId: string) => { + const verifyAssumePrivilegeToken: TAssumePrivilegeServiceFactory["verifyAssumePrivilegeToken"] = ( + token, + tokenVersionId + ) => { const appCfg = getConfig(); const decodedToken = jwt.verify(token, appCfg.AUTH_SECRET) as { tokenVersionId: string; diff --git a/backend/src/ee/services/assume-privilege/assume-privilege-types.ts b/backend/src/ee/services/assume-privilege/assume-privilege-types.ts index 55b6c8449..999fcce41 100644 --- a/backend/src/ee/services/assume-privilege/assume-privilege-types.ts +++ b/backend/src/ee/services/assume-privilege/assume-privilege-types.ts @@ -8,3 +8,28 @@ export type TAssumeProjectPrivilegeDTO = { tokenVersionId: string; actorPermissionDetails: OrgServiceActor; }; + +export interface TAssumePrivilegeServiceFactory { + assumeProjectPrivileges: ({ + targetActorType, + targetActorId, + projectId, + actorPermissionDetails, + tokenVersionId + }: TAssumeProjectPrivilegeDTO) => Promise<{ + actorType: ActorType.USER | ActorType.IDENTITY; + actorId: string; + projectId: string; + assumePrivilegesToken: string; + }>; + verifyAssumePrivilegeToken: ( + token: string, + tokenVersionId: string + ) => { + tokenVersionId: string; + projectId: string; + requesterId: string; + actorType: ActorType; + actorId: string; + }; +} diff --git a/backend/src/ee/services/audit-log-stream/audit-log-stream-dal.ts b/backend/src/ee/services/audit-log-stream/audit-log-stream-dal.ts index 436821ae9..c957890e4 100644 --- a/backend/src/ee/services/audit-log-stream/audit-log-stream-dal.ts +++ b/backend/src/ee/services/audit-log-stream/audit-log-stream-dal.ts @@ -1,10 +1,10 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TAuditLogStreamDALFactory = ReturnType; +export type TAuditLogStreamDALFactory = TOrmify; -export const auditLogStreamDALFactory = (db: TDbClient) => { +export const auditLogStreamDALFactory = (db: TDbClient): TAuditLogStreamDALFactory => { const orm = ormify(db, TableName.AuditLogStream); return orm; diff --git a/backend/src/ee/services/audit-log-stream/audit-log-stream-service.ts b/backend/src/ee/services/audit-log-stream/audit-log-stream-service.ts index c5a562a18..72207aca1 100644 --- a/backend/src/ee/services/audit-log-stream/audit-log-stream-service.ts +++ b/backend/src/ee/services/audit-log-stream/audit-log-stream-service.ts @@ -11,16 +11,9 @@ import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator"; import { AUDIT_LOG_STREAM_TIMEOUT } from "../audit-log/audit-log-queue"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TAuditLogStreamDALFactory } from "./audit-log-stream-dal"; -import { - LogStreamHeaders, - TCreateAuditLogStreamDTO, - TDeleteAuditLogStreamDTO, - TGetDetailsAuditLogStreamDTO, - TListAuditLogStreamDTO, - TUpdateAuditLogStreamDTO -} from "./audit-log-stream-types"; +import { LogStreamHeaders, TAuditLogStreamServiceFactory } from "./audit-log-stream-types"; type TAuditLogStreamServiceFactoryDep = { auditLogStreamDAL: TAuditLogStreamDALFactory; @@ -28,21 +21,19 @@ type TAuditLogStreamServiceFactoryDep = { licenseService: Pick; }; -export type TAuditLogStreamServiceFactory = ReturnType; - export const auditLogStreamServiceFactory = ({ auditLogStreamDAL, permissionService, licenseService -}: TAuditLogStreamServiceFactoryDep) => { - const create = async ({ +}: TAuditLogStreamServiceFactoryDep): TAuditLogStreamServiceFactory => { + const create: TAuditLogStreamServiceFactory["create"] = async ({ url, actor, headers = [], actorId, actorOrgId, actorAuthMethod - }: TCreateAuditLogStreamDTO) => { + }) => { if (!actorOrgId) throw new UnauthorizedError({ message: "No organization ID attached to authentication token" }); const plan = await licenseService.getPlan(actorOrgId); @@ -110,7 +101,7 @@ export const auditLogStreamServiceFactory = ({ return logStream; }; - const updateById = async ({ + const updateById: TAuditLogStreamServiceFactory["updateById"] = async ({ id, url, actor, @@ -118,7 +109,7 @@ export const auditLogStreamServiceFactory = ({ actorId, actorOrgId, actorAuthMethod - }: TUpdateAuditLogStreamDTO) => { + }) => { if (!actorOrgId) throw new UnauthorizedError({ message: "No organization ID attached to authentication token" }); const plan = await licenseService.getPlan(actorOrgId); @@ -175,7 +166,13 @@ export const auditLogStreamServiceFactory = ({ return updatedLogStream; }; - const deleteById = async ({ id, actor, actorId, actorOrgId, actorAuthMethod }: TDeleteAuditLogStreamDTO) => { + const deleteById: TAuditLogStreamServiceFactory["deleteById"] = async ({ + id, + actor, + actorId, + actorOrgId, + actorAuthMethod + }) => { if (!actorOrgId) throw new UnauthorizedError({ message: "No organization ID attached to authentication token" }); const logStream = await auditLogStreamDAL.findById(id); @@ -189,7 +186,13 @@ export const auditLogStreamServiceFactory = ({ return deletedLogStream; }; - const getById = async ({ id, actor, actorId, actorOrgId, actorAuthMethod }: TGetDetailsAuditLogStreamDTO) => { + const getById: TAuditLogStreamServiceFactory["getById"] = async ({ + id, + actor, + actorId, + actorOrgId, + actorAuthMethod + }) => { const logStream = await auditLogStreamDAL.findById(id); if (!logStream) throw new NotFoundError({ message: `Audit log stream with ID '${id}' not found` }); @@ -212,7 +215,7 @@ export const auditLogStreamServiceFactory = ({ return { ...logStream, headers }; }; - const list = async ({ actor, actorId, actorOrgId, actorAuthMethod }: TListAuditLogStreamDTO) => { + const list: TAuditLogStreamServiceFactory["list"] = async ({ actor, actorId, actorOrgId, actorAuthMethod }) => { const { permission } = await permissionService.getOrgPermission( actor, actorId, diff --git a/backend/src/ee/services/audit-log-stream/audit-log-stream-types.ts b/backend/src/ee/services/audit-log-stream/audit-log-stream-types.ts index 3c22251d7..4c4a5609e 100644 --- a/backend/src/ee/services/audit-log-stream/audit-log-stream-types.ts +++ b/backend/src/ee/services/audit-log-stream/audit-log-stream-types.ts @@ -1,3 +1,4 @@ +import { TAuditLogStreams } from "@app/db/schemas"; import { TOrgPermission } from "@app/lib/types"; export type LogStreamHeaders = { @@ -25,3 +26,23 @@ export type TListAuditLogStreamDTO = Omit; export type TGetDetailsAuditLogStreamDTO = Omit & { id: string; }; + +export type TAuditLogStreamServiceFactory = { + create: (arg: TCreateAuditLogStreamDTO) => Promise; + updateById: (arg: TUpdateAuditLogStreamDTO) => Promise; + deleteById: (arg: TDeleteAuditLogStreamDTO) => Promise; + getById: (arg: TGetDetailsAuditLogStreamDTO) => Promise<{ + headers: LogStreamHeaders[] | undefined; + orgId: string; + url: string; + id: string; + createdAt: Date; + updatedAt: Date; + encryptedHeadersCiphertext?: string | null | undefined; + encryptedHeadersIV?: string | null | undefined; + encryptedHeadersTag?: string | null | undefined; + encryptedHeadersAlgorithm?: string | null | undefined; + encryptedHeadersKeyEncoding?: string | null | undefined; + }>; + list: (arg: TListAuditLogStreamDTO) => Promise; +}; diff --git a/backend/src/ee/services/audit-log/audit-log-dal.ts b/backend/src/ee/services/audit-log/audit-log-dal.ts index ad6b72e33..874460b36 100644 --- a/backend/src/ee/services/audit-log/audit-log-dal.ts +++ b/backend/src/ee/services/audit-log/audit-log-dal.ts @@ -2,16 +2,29 @@ import knex from "knex"; import { TDbClient } from "@app/db"; -import { TableName } from "@app/db/schemas"; +import { TableName, TAuditLogs } from "@app/db/schemas"; import { DatabaseError, GatewayTimeoutError } from "@app/lib/errors"; -import { ormify, selectAllTableCols } from "@app/lib/knex"; +import { ormify, selectAllTableCols, TOrmify } from "@app/lib/knex"; import { logger } from "@app/lib/logger"; import { QueueName } from "@app/queue"; import { ActorType } from "@app/services/auth/auth-type"; import { EventType, filterableSecretEvents } from "./audit-log-types"; -export type TAuditLogDALFactory = ReturnType; +export interface TAuditLogDALFactory extends Omit, "find"> { + pruneAuditLog: (tx?: knex.Knex) => Promise; + find: ( + arg: Omit & { + actorId?: string | undefined; + actorType?: ActorType | undefined; + secretPath?: string | undefined; + secretKey?: string | undefined; + eventType?: EventType[] | undefined; + eventMetadata?: Record | undefined; + }, + tx?: knex.Knex + ) => Promise; +} type TFindQuery = { actor?: string; @@ -29,7 +42,7 @@ type TFindQuery = { export const auditLogDALFactory = (db: TDbClient) => { const auditLogOrm = ormify(db, TableName.AuditLog); - const find = async ( + const find: TAuditLogDALFactory["find"] = async ( { orgId, projectId, @@ -45,15 +58,8 @@ export const auditLogDALFactory = (db: TDbClient) => { secretKey, eventType, eventMetadata - }: Omit & { - actorId?: string; - actorType?: ActorType; - secretPath?: string; - secretKey?: string; - eventType?: EventType[]; - eventMetadata?: Record; }, - tx?: knex.Knex + tx ) => { if (!orgId && !projectId) { throw new Error("Either orgId or projectId must be provided"); @@ -154,7 +160,7 @@ export const auditLogDALFactory = (db: TDbClient) => { }; // delete all audit log that have expired - const pruneAuditLog = async (tx?: knex.Knex) => { + const pruneAuditLog: TAuditLogDALFactory["pruneAuditLog"] = async (tx) => { const AUDIT_LOG_PRUNE_BATCH_SIZE = 10000; const MAX_RETRY_ON_FAILURE = 3; diff --git a/backend/src/ee/services/audit-log/audit-log-queue.ts b/backend/src/ee/services/audit-log/audit-log-queue.ts index e312c3886..0f774e911 100644 --- a/backend/src/ee/services/audit-log/audit-log-queue.ts +++ b/backend/src/ee/services/audit-log/audit-log-queue.ts @@ -21,7 +21,9 @@ type TAuditLogQueueServiceFactoryDep = { licenseService: Pick; }; -export type TAuditLogQueueServiceFactory = Awaited>; +export type TAuditLogQueueServiceFactory = { + pushToLog: (data: TCreateAuditLogDTO) => Promise; +}; // keep this timeout 5s it must be fast because else the queue will take time to finish // audit log is a crowded queue thus needs to be fast @@ -33,7 +35,7 @@ export const auditLogQueueServiceFactory = async ({ projectDAL, licenseService, auditLogStreamDAL -}: TAuditLogQueueServiceFactoryDep) => { +}: TAuditLogQueueServiceFactoryDep): Promise => { const appCfg = getConfig(); const pushToLog = async (data: TCreateAuditLogDTO) => { diff --git a/backend/src/ee/services/audit-log/audit-log-service.ts b/backend/src/ee/services/audit-log/audit-log-service.ts index ce6689fe9..4bea26ac6 100644 --- a/backend/src/ee/services/audit-log/audit-log-service.ts +++ b/backend/src/ee/services/audit-log/audit-log-service.ts @@ -7,11 +7,11 @@ import { BadRequestError } from "@app/lib/errors"; import { ActorType } from "@app/services/auth/auth-type"; import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission"; import { TAuditLogDALFactory } from "./audit-log-dal"; import { TAuditLogQueueServiceFactory } from "./audit-log-queue"; -import { EventType, TCreateAuditLogDTO, TListProjectAuditLogDTO } from "./audit-log-types"; +import { EventType, TAuditLogServiceFactory } from "./audit-log-types"; type TAuditLogServiceFactoryDep = { auditLogDAL: TAuditLogDALFactory; @@ -19,14 +19,18 @@ type TAuditLogServiceFactoryDep = { auditLogQueue: TAuditLogQueueServiceFactory; }; -export type TAuditLogServiceFactory = ReturnType; - export const auditLogServiceFactory = ({ auditLogDAL, auditLogQueue, permissionService -}: TAuditLogServiceFactoryDep) => { - const listAuditLogs = async ({ actorAuthMethod, actorId, actorOrgId, actor, filter }: TListProjectAuditLogDTO) => { +}: TAuditLogServiceFactoryDep): TAuditLogServiceFactory => { + const listAuditLogs: TAuditLogServiceFactory["listAuditLogs"] = async ({ + actorAuthMethod, + actorId, + actorOrgId, + actor, + filter + }) => { // Filter logs for specific project if (filter.projectId) { const { permission } = await permissionService.getProjectPermission({ @@ -75,7 +79,7 @@ export const auditLogServiceFactory = ({ })); }; - const createAuditLog = async (data: TCreateAuditLogDTO) => { + const createAuditLog: TAuditLogServiceFactory["createAuditLog"] = async (data) => { const appCfg = getConfig(); if (appCfg.DISABLE_AUDIT_LOG_GENERATION) { return; diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index 87a98305f..2acf8022c 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -82,6 +82,32 @@ export type TCreateAuditLogDTO = { projectId?: string; } & BaseAuthData; +export type TAuditLogServiceFactory = { + createAuditLog: (data: TCreateAuditLogDTO) => Promise; + listAuditLogs: (arg: TListProjectAuditLogDTO) => Promise< + { + event: { + type: string; + metadata: unknown; + }; + actor: { + type: string; + metadata: unknown; + }; + id: string; + createdAt: Date; + updatedAt: Date; + orgId?: string | null | undefined; + userAgent?: string | null | undefined; + expiresAt?: Date | null | undefined; + ipAddress?: string | null | undefined; + userAgentType?: string | null | undefined; + projectId?: string | null | undefined; + projectName?: string | null | undefined; + }[] + >; +}; + export type AuditLogInfo = Pick; interface BaseAuthData { diff --git a/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-dal.ts b/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-dal.ts index d367e1616..7524d361c 100644 --- a/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-dal.ts +++ b/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-dal.ts @@ -1,10 +1,10 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TCertificateAuthorityCrlDALFactory = ReturnType; +export type TCertificateAuthorityCrlDALFactory = TOrmify; -export const certificateAuthorityCrlDALFactory = (db: TDbClient) => { +export const certificateAuthorityCrlDALFactory = (db: TDbClient): TCertificateAuthorityCrlDALFactory => { const caCrlOrm = ormify(db, TableName.CertificateAuthorityCrl); return caCrlOrm; }; diff --git a/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-service.ts b/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-service.ts index 844bda8ba..5ead798fa 100644 --- a/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-service.ts +++ b/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-service.ts @@ -3,7 +3,7 @@ import * as x509 from "@peculiar/x509"; import { ActionProjectType } from "@app/db/schemas"; import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { NotFoundError } from "@app/lib/errors"; import { TCertificateAuthorityDALFactory } from "@app/services/certificate-authority/certificate-authority-dal"; @@ -12,7 +12,7 @@ import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TProjectDALFactory } from "@app/services/project/project-dal"; import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns"; -import { TGetCaCrlsDTO, TGetCrlById } from "./certificate-authority-crl-types"; +import { TCertificateAuthorityCrlServiceFactory } from "./certificate-authority-crl-types"; type TCertificateAuthorityCrlServiceFactoryDep = { certificateAuthorityDAL: Pick; @@ -22,19 +22,17 @@ type TCertificateAuthorityCrlServiceFactoryDep = { permissionService: Pick; }; -export type TCertificateAuthorityCrlServiceFactory = ReturnType; - export const certificateAuthorityCrlServiceFactory = ({ certificateAuthorityDAL, certificateAuthorityCrlDAL, projectDAL, kmsService, permissionService // licenseService -}: TCertificateAuthorityCrlServiceFactoryDep) => { +}: TCertificateAuthorityCrlServiceFactoryDep): TCertificateAuthorityCrlServiceFactory => { /** * Return CRL with id [crlId] */ - const getCrlById = async (crlId: TGetCrlById) => { + const getCrlById: TCertificateAuthorityCrlServiceFactory["getCrlById"] = async (crlId) => { const caCrl = await certificateAuthorityCrlDAL.findById(crlId); if (!caCrl) throw new NotFoundError({ message: `CRL with ID '${crlId}' not found` }); @@ -65,7 +63,13 @@ export const certificateAuthorityCrlServiceFactory = ({ /** * Returns a list of CRL ids for CA with id [caId] */ - const getCaCrls = async ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaCrlsDTO) => { + const getCaCrls: TCertificateAuthorityCrlServiceFactory["getCaCrls"] = async ({ + caId, + actorId, + actorAuthMethod, + actor, + actorOrgId + }) => { const ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(caId); if (!ca?.internalCa?.id) throw new NotFoundError({ message: `Internal CA with ID '${caId}' not found` }); diff --git a/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-types.ts b/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-types.ts index 9b82727e9..2864bb3dd 100644 --- a/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-types.ts +++ b/backend/src/ee/services/certificate-authority-crl/certificate-authority-crl-types.ts @@ -5,3 +5,137 @@ export type TGetCrlById = string; export type TGetCaCrlsDTO = { caId: string; } & Omit; + +export type TCertificateAuthorityCrlServiceFactory = { + getCrlById: (crlId: TGetCrlById) => Promise<{ + ca: { + readonly requireTemplateForIssuance: boolean; + readonly internalCa: + | { + id: string; + parentCaId: string | null | undefined; + type: string; + friendlyName: string; + organization: string; + ou: string; + country: string; + province: string; + locality: string; + commonName: string; + dn: string; + serialNumber: string | null | undefined; + maxPathLength: number | null | undefined; + keyAlgorithm: string; + notBefore: string | undefined; + notAfter: string | undefined; + activeCaCertId: string | null | undefined; + } + | undefined; + readonly externalCa: + | { + id: string; + type: string; + configuration: unknown; + dnsAppConnectionId: string | null | undefined; + appConnectionId: string | null | undefined; + credentials: Buffer | null | undefined; + } + | undefined; + readonly name: string; + readonly status: string; + readonly id: string; + readonly createdAt: Date; + readonly updatedAt: Date; + readonly projectId: string; + readonly enableDirectIssuance: boolean; + readonly parentCaId: string | null | undefined; + readonly type: string; + readonly friendlyName: string; + readonly organization: string; + readonly ou: string; + readonly country: string; + readonly province: string; + readonly locality: string; + readonly commonName: string; + readonly dn: string; + readonly serialNumber: string | null | undefined; + readonly maxPathLength: number | null | undefined; + readonly keyAlgorithm: string; + readonly notBefore: string | undefined; + readonly notAfter: string | undefined; + readonly activeCaCertId: string | null | undefined; + }; + caCrl: { + id: string; + createdAt: Date; + updatedAt: Date; + caId: string; + caSecretId: string; + encryptedCrl: Buffer; + }; + crl: ArrayBuffer; + }>; + getCaCrls: ({ caId, actorId, actorAuthMethod, actor, actorOrgId }: TGetCaCrlsDTO) => Promise<{ + ca: { + readonly requireTemplateForIssuance: boolean; + readonly internalCa: + | { + id: string; + parentCaId: string | null | undefined; + type: string; + friendlyName: string; + organization: string; + ou: string; + country: string; + province: string; + locality: string; + commonName: string; + dn: string; + serialNumber: string | null | undefined; + maxPathLength: number | null | undefined; + keyAlgorithm: string; + notBefore: string | undefined; + notAfter: string | undefined; + activeCaCertId: string | null | undefined; + } + | undefined; + readonly externalCa: + | { + id: string; + type: string; + configuration: unknown; + dnsAppConnectionId: string | null | undefined; + appConnectionId: string | null | undefined; + credentials: Buffer | null | undefined; + } + | undefined; + readonly name: string; + readonly status: string; + readonly id: string; + readonly createdAt: Date; + readonly updatedAt: Date; + readonly projectId: string; + readonly enableDirectIssuance: boolean; + readonly parentCaId: string | null | undefined; + readonly type: string; + readonly friendlyName: string; + readonly organization: string; + readonly ou: string; + readonly country: string; + readonly province: string; + readonly locality: string; + readonly commonName: string; + readonly dn: string; + readonly serialNumber: string | null | undefined; + readonly maxPathLength: number | null | undefined; + readonly keyAlgorithm: string; + readonly notBefore: string | undefined; + readonly notAfter: string | undefined; + readonly activeCaCertId: string | null | undefined; + }; + crls: { + id: string; + crl: string; + }[]; + }>; +}; diff --git a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts index 106f72334..168b16c5f 100644 --- a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts +++ b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts @@ -3,7 +3,7 @@ import RE2 from "re2"; import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionDynamicSecretActions, ProjectPermissionSub diff --git a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts index b502bf9f3..5a7da6a3e 100644 --- a/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts +++ b/backend/src/ee/services/dynamic-secret/dynamic-secret-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionDynamicSecretActions, ProjectPermissionSub diff --git a/backend/src/ee/services/external-kms/external-kms-service.ts b/backend/src/ee/services/external-kms/external-kms-service.ts index 4d7b1a5b5..d515c5973 100644 --- a/backend/src/ee/services/external-kms/external-kms-service.ts +++ b/backend/src/ee/services/external-kms/external-kms-service.ts @@ -11,7 +11,7 @@ import { KmsDataKey, KmsKeyUsage } from "@app/services/kms/kms-types"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TExternalKmsDALFactory } from "./external-kms-dal"; import { TCreateExternalKmsDTO, diff --git a/backend/src/ee/services/gateway/gateway-service.ts b/backend/src/ee/services/gateway/gateway-service.ts index 25f0b384a..ffef3e007 100644 --- a/backend/src/ee/services/gateway/gateway-service.ts +++ b/backend/src/ee/services/gateway/gateway-service.ts @@ -21,7 +21,7 @@ import { KmsDataKey } from "@app/services/kms/kms-types"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionGatewayActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TGatewayDALFactory } from "./gateway-dal"; import { TExchangeAllocatedRelayAddressDTO, diff --git a/backend/src/ee/services/github-org-sync/github-org-sync-service.ts b/backend/src/ee/services/github-org-sync/github-org-sync-service.ts index 867feb4a4..37d1bd398 100644 --- a/backend/src/ee/services/github-org-sync/github-org-sync-service.ts +++ b/backend/src/ee/services/github-org-sync/github-org-sync-service.ts @@ -14,7 +14,7 @@ import { TGroupDALFactory } from "../group/group-dal"; import { TUserGroupMembershipDALFactory } from "../group/user-group-membership-dal"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TGithubOrgSyncDALFactory } from "./github-org-sync-dal"; import { TCreateGithubOrgSyncDTO, TDeleteGithubOrgSyncDTO, TUpdateGithubOrgSyncDTO } from "./github-org-sync-types"; diff --git a/backend/src/ee/services/group/group-service.ts b/backend/src/ee/services/group/group-service.ts index cc3125918..55665c146 100644 --- a/backend/src/ee/services/group/group-service.ts +++ b/backend/src/ee/services/group/group-service.ts @@ -15,7 +15,7 @@ import { TUserDALFactory } from "@app/services/user/user-dal"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionGroupActions, OrgPermissionSubjects } from "../permission/org-permission"; import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "../permission/permission-fns"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TGroupDALFactory } from "./group-dal"; import { addUsersToGroupByUserIds, removeUsersFromGroupByUserIds } from "./group-fns"; import { diff --git a/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts b/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts index bf75ce5cd..64da588f8 100644 --- a/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts +++ b/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts @@ -11,7 +11,7 @@ import { TIdentityProjectDALFactory } from "@app/services/identity-project/ident import { TProjectDALFactory } from "@app/services/project/project-dal"; import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "../permission/permission-fns"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "../permission/project-permission"; import { TIdentityProjectAdditionalPrivilegeV2DALFactory } from "./identity-project-additional-privilege-v2-dal"; import { diff --git a/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts b/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts index cbfcc4670..828cf43a3 100644 --- a/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts +++ b/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts @@ -11,7 +11,7 @@ import { TIdentityProjectDALFactory } from "@app/services/identity-project/ident import { TProjectDALFactory } from "@app/services/project/project-dal"; import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "../permission/permission-fns"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionIdentityActions, ProjectPermissionSet, diff --git a/backend/src/ee/services/kmip/kmip-operation-service.ts b/backend/src/ee/services/kmip/kmip-operation-service.ts index 45f201498..55d8c2b42 100644 --- a/backend/src/ee/services/kmip/kmip-operation-service.ts +++ b/backend/src/ee/services/kmip/kmip-operation-service.ts @@ -7,7 +7,7 @@ import { KmsKeyUsage } from "@app/services/kms/kms-types"; import { TProjectDALFactory } from "@app/services/project/project-dal"; import { OrgPermissionKmipActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TKmipClientDALFactory } from "./kmip-client-dal"; import { KmipPermission } from "./kmip-enum"; import { diff --git a/backend/src/ee/services/kmip/kmip-service.ts b/backend/src/ee/services/kmip/kmip-service.ts index 82ff1a9aa..f8c52fe56 100644 --- a/backend/src/ee/services/kmip/kmip-service.ts +++ b/backend/src/ee/services/kmip/kmip-service.ts @@ -18,7 +18,7 @@ import { KmsDataKey } from "@app/services/kms/kms-types"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionKmipActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionKmipActions, ProjectPermissionSub } from "../permission/project-permission"; import { TKmipClientCertificateDALFactory } from "./kmip-client-certificate-dal"; import { TKmipClientDALFactory } from "./kmip-client-dal"; diff --git a/backend/src/ee/services/ldap-config/ldap-config-service.ts b/backend/src/ee/services/ldap-config/ldap-config-service.ts index c98873879..426ed132e 100644 --- a/backend/src/ee/services/ldap-config/ldap-config-service.ts +++ b/backend/src/ee/services/ldap-config/ldap-config-service.ts @@ -29,7 +29,7 @@ import { UserAliasType } from "@app/services/user-alias/user-alias-types"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TLdapConfigDALFactory } from "./ldap-config-dal"; import { TCreateLdapCfgDTO, diff --git a/backend/src/ee/services/license/license-service.ts b/backend/src/ee/services/license/license-service.ts index 80e58815e..b841c5bea 100644 --- a/backend/src/ee/services/license/license-service.ts +++ b/backend/src/ee/services/license/license-service.ts @@ -18,7 +18,7 @@ import { TOrgDALFactory } from "@app/services/org/org-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal"; import { OrgPermissionBillingActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { BillingPlanRows, BillingPlanTableHead } from "./licence-enums"; import { TLicenseDALFactory } from "./license-dal"; import { getDefaultOnPremFeatures, setupLicenseRequestWithStore } from "./license-fns"; diff --git a/backend/src/ee/services/oidc/oidc-config-service.ts b/backend/src/ee/services/oidc/oidc-config-service.ts index d933835e4..5cbfbbc97 100644 --- a/backend/src/ee/services/oidc/oidc-config-service.ts +++ b/backend/src/ee/services/oidc/oidc-config-service.ts @@ -5,14 +5,13 @@ import { Issuer, Issuer as OpenIdIssuer, Strategy as OpenIdStrategy, TokenSet } import { OrgMembershipStatus, TableName, TUsers } from "@app/db/schemas"; import { TOidcConfigsUpdate } from "@app/db/schemas/oidc-configs"; -import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service"; -import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types"; import { TGroupDALFactory } from "@app/ee/services/group/group-dal"; import { addUsersToGroupByUserIds, removeUsersFromGroupByUserIds } from "@app/ee/services/group/group-fns"; import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError, OidcAuthError } from "@app/lib/errors"; import { OrgServiceActor } from "@app/lib/types"; diff --git a/backend/src/ee/services/permission/permission-dal.ts b/backend/src/ee/services/permission/permission-dal.ts index 7a17108a2..11ee29852 100644 --- a/backend/src/ee/services/permission/permission-dal.ts +++ b/backend/src/ee/services/permission/permission-dal.ts @@ -6,16 +6,312 @@ import { OrgMembershipRole, OrgMembershipsSchema, TableName, + TIdentityOrgMemberships, TProjectRoles, TProjects } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; import { selectAllTableCols, sqlNestRelationships } from "@app/lib/knex"; -export type TPermissionDALFactory = ReturnType; +export interface TPermissionDALFactory { + getOrgPermission: ( + userId: string, + orgId: string + ) => Promise< + { + status: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + role: string; + isActive: boolean; + shouldUseNewPrivilegeSystem: boolean; + bypassOrgAuthEnabled: boolean; + permissions?: unknown; + userId?: string | null | undefined; + roleId?: string | null | undefined; + inviteEmail?: string | null | undefined; + projectFavorites?: string[] | null | undefined; + customRoleSlug?: string | null | undefined; + orgAuthEnforced?: boolean | null | undefined; + } & { + groups: { + id: string; + updatedAt: Date; + createdAt: Date; + role: string; + roleId: string | null | undefined; + customRolePermission: unknown; + name: string; + slug: string; + orgId: string; + }[]; + } + >; + getOrgIdentityPermission: ( + identityId: string, + orgId: string + ) => Promise< + | (TIdentityOrgMemberships & { + orgAuthEnforced: boolean | null | undefined; + shouldUseNewPrivilegeSystem: boolean; + permissions?: unknown; + }) + | undefined + >; + getProjectPermission: ( + userId: string, + projectId: string + ) => Promise< + | { + roles: { + id: string; + role: string; + customRoleSlug: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + additionalPrivileges: { + id: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + orgId: string; + orgAuthEnforced: boolean | null | undefined; + orgRole: OrgMembershipRole; + userId: string; + projectId: string; + username: string; + projectType: string; + id: string; + createdAt: Date; + updatedAt: Date; + shouldUseNewPrivilegeSystem: boolean; + bypassOrgAuthEnabled: boolean; + metadata: { + id: string; + key: string; + value: string; + }[]; + userGroupRoles: { + id: string; + role: string; + customRoleSlug: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + projecMembershiptRoles: { + id: string; + role: string; + customRoleSlug: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + } + | undefined + >; + getProjectIdentityPermission: ( + identityId: string, + projectId: string + ) => Promise< + | { + roles: { + id: string; + createdAt: Date; + updatedAt: Date; + isTemporary: boolean; + role: string; + projectMembershipId: string; + temporaryRange?: string | null | undefined; + permissions?: unknown; + customRoleId?: string | null | undefined; + temporaryMode?: string | null | undefined; + temporaryAccessStartTime?: Date | null | undefined; + temporaryAccessEndTime?: Date | null | undefined; + customRoleSlug?: string | null | undefined; + }[]; + additionalPrivileges: { + id: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + isTemporary: boolean; + }[]; + id: string; + identityId: string; + username: string; + projectId: string; + createdAt: Date; + updatedAt: Date; + orgId: string; + projectType: string; + shouldUseNewPrivilegeSystem: boolean; + orgAuthEnforced: boolean; + metadata: { + id: string; + key: string; + value: string; + }[]; + } + | undefined + >; + getProjectUserPermissions: (projectId: string) => Promise< + { + roles: { + id: string; + role: string; + customRoleSlug: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + additionalPrivileges: { + id: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + orgId: string; + orgAuthEnforced: boolean | null | undefined; + userId: string; + projectId: string; + username: string; + projectType: string; + id: string; + createdAt: Date; + updatedAt: Date; + metadata: { + id: string; + key: string; + value: string; + }[]; + userGroupRoles: { + id: string; + role: string; + customRoleSlug: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + projectMembershipRoles: { + id: string; + role: string; + customRoleSlug: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + }[] + >; + getProjectIdentityPermissions: (projectId: string) => Promise< + { + roles: { + id: string; + createdAt: Date; + updatedAt: Date; + isTemporary: boolean; + role: string; + projectMembershipId: string; + temporaryRange?: string | null | undefined; + permissions?: unknown; + customRoleId?: string | null | undefined; + temporaryMode?: string | null | undefined; + temporaryAccessStartTime?: Date | null | undefined; + temporaryAccessEndTime?: Date | null | undefined; + customRoleSlug?: string | null | undefined; + }[]; + additionalPrivileges: { + id: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + isTemporary: boolean; + }[]; + id: string; + identityId: string; + username: string; + projectId: string; + createdAt: Date; + updatedAt: Date; + orgId: string; + projectType: string; + orgAuthEnforced: boolean; + metadata: { + id: string; + key: string; + value: string; + }[]; + }[] + >; + getProjectGroupPermissions: ( + projectId: string, + filterGroupId?: string + ) => Promise< + { + roles: { + id: string; + role: string; + customRoleSlug: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + groupId: string; + username: string; + id: string; + groupRoles: { + id: string; + role: string; + customRoleSlug: string; + permissions: unknown; + temporaryRange: string | null | undefined; + temporaryMode: string | null | undefined; + temporaryAccessStartTime: Date | null | undefined; + temporaryAccessEndTime: Date | null | undefined; + isTemporary: boolean; + }[]; + }[] + >; +} -export const permissionDALFactory = (db: TDbClient) => { - const getOrgPermission = async (userId: string, orgId: string) => { +export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => { + const getOrgPermission: TPermissionDALFactory["getOrgPermission"] = async (userId: string, orgId: string) => { try { const groupSubQuery = db(TableName.Groups) .where(`${TableName.Groups}.orgId`, orgId) @@ -112,7 +408,10 @@ export const permissionDALFactory = (db: TDbClient) => { } }; - const getOrgIdentityPermission = async (identityId: string, orgId: string) => { + const getOrgIdentityPermission: TPermissionDALFactory["getOrgIdentityPermission"] = async ( + identityId: string, + orgId: string + ) => { try { const membership = await db .replicaNode()(TableName.IdentityOrgMembership) @@ -132,7 +431,10 @@ export const permissionDALFactory = (db: TDbClient) => { } }; - const getProjectGroupPermissions = async (projectId: string, filterGroupId?: string) => { + const getProjectGroupPermissions: TPermissionDALFactory["getProjectGroupPermissions"] = async ( + projectId: string, + filterGroupId?: string + ) => { try { const docs = await db .replicaNode()(TableName.GroupProjectMembership) @@ -245,7 +547,7 @@ export const permissionDALFactory = (db: TDbClient) => { } }; - const getProjectUserPermissions = async (projectId: string) => { + const getProjectUserPermissions: TPermissionDALFactory["getProjectUserPermissions"] = async (projectId: string) => { try { const docs = await db .replicaNode()(TableName.Users) @@ -535,7 +837,10 @@ export const permissionDALFactory = (db: TDbClient) => { } }; - const getProjectPermission = async (userId: string, projectId: string) => { + const getProjectPermission: TPermissionDALFactory["getProjectPermission"] = async ( + userId: string, + projectId: string + ) => { try { const subQueryUserGroups = db(TableName.UserGroupMembership).where("userId", userId).select("groupId"); const docs = await db @@ -838,7 +1143,9 @@ export const permissionDALFactory = (db: TDbClient) => { } }; - const getProjectIdentityPermissions = async (projectId: string) => { + const getProjectIdentityPermissions: TPermissionDALFactory["getProjectIdentityPermissions"] = async ( + projectId: string + ) => { try { const docs = await db .replicaNode()(TableName.IdentityProjectMembership) @@ -995,7 +1302,10 @@ export const permissionDALFactory = (db: TDbClient) => { } }; - const getProjectIdentityPermission = async (identityId: string, projectId: string) => { + const getProjectIdentityPermission: TPermissionDALFactory["getProjectIdentityPermission"] = async ( + identityId, + projectId + ) => { try { const docs = await db .replicaNode()(TableName.IdentityProjectMembership) diff --git a/backend/src/ee/services/permission/permission-service-types.ts b/backend/src/ee/services/permission/permission-service-types.ts index 570e2b6b1..5e71c65d9 100644 --- a/backend/src/ee/services/permission/permission-service-types.ts +++ b/backend/src/ee/services/permission/permission-service-types.ts @@ -1,6 +1,12 @@ +import { MongoAbility, RawRuleOf } from "@casl/ability"; +import { MongoQuery } from "@ucast/mongo2js"; + import { ActionProjectType } from "@app/db/schemas"; import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type"; +import { OrgPermissionSet } from "./org-permission"; +import { ProjectPermissionSet } from "./project-permission"; + export type TBuildProjectPermissionDTO = { permissions?: unknown; role: string; @@ -41,3 +47,240 @@ export type TGetProjectPermissionArg = { actorOrgId?: string; actionProjectType: ActionProjectType; }; + +export type TPermissionServiceFactory = { + getUserOrgPermission: ( + userId: string, + orgId: string, + authMethod: ActorAuthMethod, + userOrgId?: string + ) => Promise<{ + permission: MongoAbility; + membership: { + status: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + role: string; + isActive: boolean; + shouldUseNewPrivilegeSystem: boolean; + bypassOrgAuthEnabled: boolean; + permissions?: unknown; + userId?: string | null | undefined; + roleId?: string | null | undefined; + inviteEmail?: string | null | undefined; + projectFavorites?: string[] | null | undefined; + customRoleSlug?: string | null | undefined; + orgAuthEnforced?: boolean | null | undefined; + } & { + groups: { + id: string; + updatedAt: Date; + createdAt: Date; + role: string; + roleId: string | null | undefined; + customRolePermission: unknown; + name: string; + slug: string; + orgId: string; + }[]; + }; + }>; + getOrgPermission: ( + type: ActorType, + id: string, + orgId: string, + authMethod: ActorAuthMethod, + actorOrgId: string | undefined + ) => Promise< + | { + permission: MongoAbility; + membership: { + status: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + role: string; + isActive: boolean; + shouldUseNewPrivilegeSystem: boolean; + bypassOrgAuthEnabled: boolean; + permissions?: unknown; + userId?: string | null | undefined; + roleId?: string | null | undefined; + inviteEmail?: string | null | undefined; + projectFavorites?: string[] | null | undefined; + customRoleSlug?: string | null | undefined; + orgAuthEnforced?: boolean | null | undefined; + } & { + groups: { + id: string; + updatedAt: Date; + createdAt: Date; + role: string; + roleId: string | null | undefined; + customRolePermission: unknown; + name: string; + slug: string; + orgId: string; + }[]; + }; + } + | { + permission: MongoAbility; + membership: { + id: string; + role: string; + createdAt: Date; + updatedAt: Date; + orgId: string; + roleId?: string | null | undefined; + permissions?: unknown; + identityId: string; + orgAuthEnforced: boolean | null | undefined; + shouldUseNewPrivilegeSystem: boolean; + }; + } + >; + getUserProjectPermission: ({ + userId, + projectId, + authMethod, + userOrgId, + actionProjectType + }: TGetUserProjectPermissionArg) => Promise<{ + permission: MongoAbility; + membership: { + id: string; + createdAt: Date; + updatedAt: Date; + userId: string; + projectId: string; + } & { + orgAuthEnforced: boolean | null | undefined; + orgId: string; + roles: Array<{ + role: string; + }>; + shouldUseNewPrivilegeSystem: boolean; + }; + hasRole: (role: string) => boolean; + }>; + getProjectPermission: ( + arg: TGetProjectPermissionArg + ) => Promise< + T extends ActorType.SERVICE + ? { + permission: MongoAbility; + membership: { + shouldUseNewPrivilegeSystem: boolean; + }; + hasRole: (arg: string) => boolean; + } + : { + permission: MongoAbility; + membership: (T extends ActorType.USER + ? { + id: string; + createdAt: Date; + updatedAt: Date; + userId: string; + projectId: string; + } + : { + id: string; + createdAt: Date; + updatedAt: Date; + projectId: string; + identityId: string; + }) & { + orgAuthEnforced: boolean | null | undefined; + orgId: string; + roles: Array<{ + role: string; + }>; + shouldUseNewPrivilegeSystem: boolean; + }; + hasRole: (role: string) => boolean; + } + >; + getProjectPermissions: (projectId: string) => Promise<{ + userPermissions: { + permission: MongoAbility; + id: string; + name: string; + membershipId: string; + }[]; + identityPermissions: { + permission: MongoAbility; + id: string; + name: string; + membershipId: string; + }[]; + groupPermissions: { + permission: MongoAbility; + id: string; + name: string; + membershipId: string; + }[]; + }>; + getOrgPermissionByRole: ( + role: string, + orgId: string + ) => Promise< + | { + permission: MongoAbility; + role: { + name: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + slug: string; + permissions?: unknown; + description?: string | null | undefined; + }; + } + | { + permission: MongoAbility; + role?: undefined; + } + >; + getProjectPermissionByRole: ( + role: string, + projectId: string + ) => Promise< + | { + permission: MongoAbility; + role: { + name: string; + version: number; + id: string; + createdAt: Date; + updatedAt: Date; + projectId: string; + slug: string; + permissions?: unknown; + description?: string | null | undefined; + }; + } + | { + permission: MongoAbility; + role?: undefined; + } + >; + buildOrgPermission: (orgUserRoles: TBuildOrgPermissionDTO) => MongoAbility; + buildProjectPermissionRules: ( + projectUserRoles: TBuildProjectPermissionDTO + ) => RawRuleOf>[]; + checkGroupProjectPermission: ({ + groupId, + projectId, + checkPermissions + }: { + groupId: string; + projectId: string; + checkPermissions: ProjectPermissionSet; + }) => Promise; +}; diff --git a/backend/src/ee/services/permission/permission-service.ts b/backend/src/ee/services/permission/permission-service.ts index a1acaeb21..85ee82cca 100644 --- a/backend/src/ee/services/permission/permission-service.ts +++ b/backend/src/ee/services/permission/permission-service.ts @@ -23,7 +23,7 @@ import { import { conditionsMatcher } from "@app/lib/casl"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { objectify } from "@app/lib/fn"; -import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type"; +import { ActorType } from "@app/services/auth/auth-type"; import { TOrgRoleDALFactory } from "@app/services/org/org-role-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectRoleDALFactory } from "@app/services/project-role/project-role-dal"; @@ -38,7 +38,8 @@ import { TGetIdentityProjectPermissionArg, TGetProjectPermissionArg, TGetServiceTokenProjectPermissionArg, - TGetUserProjectPermissionArg + TGetUserProjectPermissionArg, + TPermissionServiceFactory } from "./permission-service-types"; import { buildServiceTokenProjectPermission, ProjectPermissionSet } from "./project-permission"; @@ -50,15 +51,13 @@ type TPermissionServiceFactoryDep = { permissionDAL: TPermissionDALFactory; }; -export type TPermissionServiceFactory = ReturnType; - export const permissionServiceFactory = ({ permissionDAL, orgRoleDAL, projectRoleDAL, serviceTokenDAL, projectDAL -}: TPermissionServiceFactoryDep) => { +}: TPermissionServiceFactoryDep): TPermissionServiceFactory => { const buildOrgPermission = (orgUserRoles: TBuildOrgPermissionDTO) => { const rules = orgUserRoles .map(({ role, permissions }) => { @@ -120,11 +119,11 @@ export const permissionServiceFactory = ({ /* * Get user permission in an organization */ - const getUserOrgPermission = async ( - userId: string, - orgId: string, - authMethod: ActorAuthMethod, - userOrgId?: string + const getUserOrgPermission: TPermissionServiceFactory["getUserOrgPermission"] = async ( + userId, + orgId, + authMethod, + userOrgId ) => { // when token is scoped, ensure the passed org id is same as user org id if (userOrgId && userOrgId !== orgId) @@ -172,12 +171,12 @@ export const permissionServiceFactory = ({ }; }; - const getOrgPermission = async ( - type: ActorType, - id: string, - orgId: string, - authMethod: ActorAuthMethod, - actorOrgId: string | undefined + const getOrgPermission: TPermissionServiceFactory["getOrgPermission"] = async ( + type, + id, + orgId, + authMethod, + actorOrgId ) => { switch (type) { case ActorType.USER: @@ -194,7 +193,7 @@ export const permissionServiceFactory = ({ // instead of actor type this will fetch by role slug. meaning it can be the pre defined slugs like // admin member or user defined ones like biller etc - const getOrgPermissionByRole = async (role: string, orgId: string) => { + const getOrgPermissionByRole: TPermissionServiceFactory["getOrgPermissionByRole"] = async (role, orgId) => { const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole); if (isCustomRole) { const orgRole = await orgRoleDAL.findOne({ slug: role, orgId }); @@ -437,7 +436,7 @@ export const permissionServiceFactory = ({ hasRole: (role: string) => boolean; }; - const getProjectPermissions = async (projectId: string) => { + const getProjectPermissions: TPermissionServiceFactory["getProjectPermissions"] = async (projectId) => { // fetch user permissions const rawUserProjectPermissions = await permissionDAL.getProjectUserPermissions(projectId); const userPermissions = rawUserProjectPermissions.map((userProjectPermission) => { @@ -607,7 +606,10 @@ export const permissionServiceFactory = ({ } }; - const getProjectPermissionByRole = async (role: string, projectId: string) => { + const getProjectPermissionByRole: TPermissionServiceFactory["getProjectPermissionByRole"] = async ( + role, + projectId + ) => { const isCustomRole = !Object.values(ProjectMembershipRole).includes(role as ProjectMembershipRole); if (isCustomRole) { const projectRole = await projectRoleDAL.findOne({ slug: role, projectId }); @@ -630,14 +632,10 @@ export const permissionServiceFactory = ({ return { permission }; }; - const checkGroupProjectPermission = async ({ + const checkGroupProjectPermission: TPermissionServiceFactory["checkGroupProjectPermission"] = async ({ groupId, projectId, checkPermissions - }: { - groupId: string; - projectId: string; - checkPermissions: ProjectPermissionSet; }) => { const rawGroupProjectPermissions = await permissionDAL.getProjectGroupPermissions(projectId, groupId); const groupPermissions = rawGroupProjectPermissions.map((groupProjectPermission) => { diff --git a/backend/src/ee/services/pit/pit-service.ts b/backend/src/ee/services/pit/pit-service.ts index 160729123..0eb223fb4 100644 --- a/backend/src/ee/services/pit/pit-service.ts +++ b/backend/src/ee/services/pit/pit-service.ts @@ -16,7 +16,7 @@ import { TSecretServiceFactory } from "@app/services/secret/secret-service"; import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-folder-dal"; import { TSecretFolderServiceFactory } from "@app/services/secret-folder/secret-folder-service"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; type TPitServiceFactoryDep = { folderCommitService: TFolderCommitServiceFactory; diff --git a/backend/src/ee/services/project-template/project-template-dal.ts b/backend/src/ee/services/project-template/project-template-dal.ts index 4dbbea279..b3663d6f4 100644 --- a/backend/src/ee/services/project-template/project-template-dal.ts +++ b/backend/src/ee/services/project-template/project-template-dal.ts @@ -1,7 +1,8 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TProjectTemplateDALFactory = ReturnType; +export type TProjectTemplateDALFactory = TOrmify; -export const projectTemplateDALFactory = (db: TDbClient) => ormify(db, TableName.ProjectTemplates); +export const projectTemplateDALFactory = (db: TDbClient): TProjectTemplateDALFactory => + ormify(db, TableName.ProjectTemplates); diff --git a/backend/src/ee/services/project-template/project-template-service.ts b/backend/src/ee/services/project-template/project-template-service.ts index 5b6163977..9d585fc9a 100644 --- a/backend/src/ee/services/project-template/project-template-service.ts +++ b/backend/src/ee/services/project-template/project-template-service.ts @@ -4,18 +4,16 @@ import { packRules } from "@casl/ability/extra"; import { ProjectType, TProjectTemplates } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectTemplateDefaultEnvironments } from "@app/ee/services/project-template/project-template-constants"; import { getDefaultProjectTemplate } from "@app/ee/services/project-template/project-template-fns"; import { - TCreateProjectTemplateDTO, TProjectTemplateEnvironment, TProjectTemplateRole, - TUnpackedPermission, - TUpdateProjectTemplateDTO + TProjectTemplateServiceFactory, + TUnpackedPermission } from "@app/ee/services/project-template/project-template-types"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; -import { OrgServiceActor } from "@app/lib/types"; import { unpackPermissions } from "@app/server/routes/sanitizedSchema/permission"; import { getPredefinedRoles } from "@app/services/project-role/project-role-fns"; @@ -27,8 +25,6 @@ type TProjectTemplatesServiceFactoryDep = { projectTemplateDAL: TProjectTemplateDALFactory; }; -export type TProjectTemplateServiceFactory = ReturnType; - const $unpackProjectTemplate = ({ roles, environments, ...rest }: TProjectTemplates) => ({ ...rest, environments: environments as TProjectTemplateEnvironment[], @@ -51,8 +47,11 @@ export const projectTemplateServiceFactory = ({ licenseService, permissionService, projectTemplateDAL -}: TProjectTemplatesServiceFactoryDep) => { - const listProjectTemplatesByOrg = async (actor: OrgServiceActor, type?: ProjectType) => { +}: TProjectTemplatesServiceFactoryDep): TProjectTemplateServiceFactory => { + const listProjectTemplatesByOrg: TProjectTemplateServiceFactory["listProjectTemplatesByOrg"] = async ( + actor, + type + ) => { const plan = await licenseService.getPlan(actor.orgId); if (!plan.projectTemplates) @@ -83,7 +82,10 @@ export const projectTemplateServiceFactory = ({ ]; }; - const findProjectTemplateByName = async (name: string, actor: OrgServiceActor) => { + const findProjectTemplateByName: TProjectTemplateServiceFactory["findProjectTemplateByName"] = async ( + name, + actor + ) => { const plan = await licenseService.getPlan(actor.orgId); if (!plan.projectTemplates) @@ -111,7 +113,7 @@ export const projectTemplateServiceFactory = ({ }; }; - const findProjectTemplateById = async (id: string, actor: OrgServiceActor) => { + const findProjectTemplateById: TProjectTemplateServiceFactory["findProjectTemplateById"] = async (id, actor) => { const plan = await licenseService.getPlan(actor.orgId); if (!plan.projectTemplates) @@ -139,9 +141,9 @@ export const projectTemplateServiceFactory = ({ }; }; - const createProjectTemplate = async ( - { roles, environments, type, ...params }: TCreateProjectTemplateDTO, - actor: OrgServiceActor + const createProjectTemplate: TProjectTemplateServiceFactory["createProjectTemplate"] = async ( + { roles, environments, type, ...params }, + actor ) => { const plan = await licenseService.getPlan(actor.orgId); @@ -195,10 +197,10 @@ export const projectTemplateServiceFactory = ({ return $unpackProjectTemplate(projectTemplate); }; - const updateProjectTemplateById = async ( - id: string, - { roles, environments, ...params }: TUpdateProjectTemplateDTO, - actor: OrgServiceActor + const updateProjectTemplateById: TProjectTemplateServiceFactory["updateProjectTemplateById"] = async ( + id, + { roles, environments, ...params }, + actor ) => { const plan = await licenseService.getPlan(actor.orgId); @@ -259,7 +261,7 @@ export const projectTemplateServiceFactory = ({ return $unpackProjectTemplate(updatedProjectTemplate); }; - const deleteProjectTemplateById = async (id: string, actor: OrgServiceActor) => { + const deleteProjectTemplateById: TProjectTemplateServiceFactory["deleteProjectTemplateById"] = async (id, actor) => { const plan = await licenseService.getPlan(actor.orgId); if (!plan.projectTemplates) diff --git a/backend/src/ee/services/project-template/project-template-types.ts b/backend/src/ee/services/project-template/project-template-types.ts index d53b2375e..2684e10e5 100644 --- a/backend/src/ee/services/project-template/project-template-types.ts +++ b/backend/src/ee/services/project-template/project-template-types.ts @@ -1,7 +1,8 @@ import { z } from "zod"; -import { ProjectType, TProjectEnvironments } from "@app/db/schemas"; +import { ProjectMembershipRole, ProjectType, TProjectEnvironments } from "@app/db/schemas"; import { TProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; +import { OrgServiceActor } from "@app/lib/types"; import { UnpackedPermissionSchema } from "@app/server/routes/sanitizedSchema/permission"; export type TProjectTemplateEnvironment = Pick; @@ -27,3 +28,177 @@ export type TUnpackedPermission = z.infer; export enum InfisicalProjectTemplate { Default = "default" } + +export type TProjectTemplateServiceFactory = { + listProjectTemplatesByOrg: ( + actor: OrgServiceActor, + type?: ProjectType + ) => Promise< + ( + | { + id: string; + type: ProjectType; + name: InfisicalProjectTemplate; + createdAt: Date; + updatedAt: Date; + description: string; + environments: + | { + name: string; + slug: string; + position: number; + }[] + | null; + roles: { + name: string; + slug: ProjectMembershipRole; + permissions: { + action: string[]; + subject?: string | undefined; + conditions?: unknown; + inverted?: boolean | undefined; + }[]; + }[]; + orgId: string; + } + | { + environments: TProjectTemplateEnvironment[]; + roles: { + permissions: { + action: string[]; + subject?: string | undefined; + conditions?: unknown; + inverted?: boolean | undefined; + }[]; + slug: string; + name: string; + }[]; + name: string; + type: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + description?: string | null | undefined; + } + )[] + >; + createProjectTemplate: ( + arg: TCreateProjectTemplateDTO, + actor: OrgServiceActor + ) => Promise<{ + environments: TProjectTemplateEnvironment[]; + roles: { + permissions: { + action: string[]; + subject?: string | undefined; + conditions?: unknown; + inverted?: boolean | undefined; + }[]; + slug: string; + name: string; + }[]; + name: string; + type: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + description?: string | null | undefined; + }>; + updateProjectTemplateById: ( + id: string, + { roles, environments, ...params }: TUpdateProjectTemplateDTO, + actor: OrgServiceActor + ) => Promise<{ + environments: TProjectTemplateEnvironment[]; + roles: { + permissions: { + action: string[]; + subject?: string | undefined; + conditions?: unknown; + inverted?: boolean | undefined; + }[]; + slug: string; + name: string; + }[]; + name: string; + type: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + description?: string | null | undefined; + }>; + deleteProjectTemplateById: ( + id: string, + actor: OrgServiceActor + ) => Promise<{ + environments: TProjectTemplateEnvironment[]; + roles: { + permissions: { + action: string[]; + subject?: string | undefined; + conditions?: unknown; + inverted?: boolean | undefined; + }[]; + slug: string; + name: string; + }[]; + name: string; + type: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + description?: string | null | undefined; + }>; + findProjectTemplateById: ( + id: string, + actor: OrgServiceActor + ) => Promise<{ + packedRoles: TProjectTemplateRole[]; + environments: TProjectTemplateEnvironment[]; + roles: { + permissions: { + action: string[]; + subject?: string | undefined; + conditions?: unknown; + inverted?: boolean | undefined; + }[]; + slug: string; + name: string; + }[]; + name: string; + type: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + description?: string | null | undefined; + }>; + findProjectTemplateByName: ( + name: string, + actor: OrgServiceActor + ) => Promise<{ + packedRoles: TProjectTemplateRole[]; + environments: TProjectTemplateEnvironment[]; + roles: { + permissions: { + action: string[]; + subject?: string | undefined; + conditions?: unknown; + inverted?: boolean | undefined; + }[]; + slug: string; + name: string; + }[]; + name: string; + type: string; + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + description?: string | null | undefined; + }>; +}; diff --git a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal.ts b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal.ts index 6c15d2d5d..6a3be2631 100644 --- a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal.ts +++ b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal.ts @@ -1,10 +1,10 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TProjectUserAdditionalPrivilegeDALFactory = ReturnType; +export type TProjectUserAdditionalPrivilegeDALFactory = TOrmify; -export const projectUserAdditionalPrivilegeDALFactory = (db: TDbClient) => { +export const projectUserAdditionalPrivilegeDALFactory = (db: TDbClient): TProjectUserAdditionalPrivilegeDALFactory => { const orm = ormify(db, TableName.ProjectUserAdditionalPrivilege); return orm; }; diff --git a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts index f4d7f4e6a..944775156 100644 --- a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts +++ b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts @@ -11,7 +11,7 @@ import { TProjectMembershipDALFactory } from "@app/services/project-membership/p import { TAccessApprovalRequestDALFactory } from "../access-approval-request/access-approval-request-dal"; import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "../permission/permission-fns"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionMemberActions, ProjectPermissionSet, @@ -21,11 +21,7 @@ import { ApprovalStatus } from "../secret-approval-request/secret-approval-reque import { TProjectUserAdditionalPrivilegeDALFactory } from "./project-user-additional-privilege-dal"; import { ProjectUserAdditionalPrivilegeTemporaryMode, - TCreateUserPrivilegeDTO, - TDeleteUserPrivilegeDTO, - TGetUserPrivilegeDetailsDTO, - TListUserPrivilegesDTO, - TUpdateUserPrivilegeDTO + TProjectUserAdditionalPrivilegeServiceFactory } from "./project-user-additional-privilege-types"; type TProjectUserAdditionalPrivilegeServiceFactoryDep = { @@ -35,10 +31,6 @@ type TProjectUserAdditionalPrivilegeServiceFactoryDep = { accessApprovalRequestDAL: Pick; }; -export type TProjectUserAdditionalPrivilegeServiceFactory = ReturnType< - typeof projectUserAdditionalPrivilegeServiceFactory ->; - const unpackPermissions = (permissions: unknown) => UnpackedPermissionSchema.array().parse( unpackRules((permissions || []) as PackRule>>[]) @@ -49,8 +41,8 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ projectMembershipDAL, permissionService, accessApprovalRequestDAL -}: TProjectUserAdditionalPrivilegeServiceFactoryDep) => { - const create = async ({ +}: TProjectUserAdditionalPrivilegeServiceFactoryDep): TProjectUserAdditionalPrivilegeServiceFactory => { + const create: TProjectUserAdditionalPrivilegeServiceFactory["create"] = async ({ slug, actor, actorId, @@ -59,7 +51,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ actorAuthMethod, projectMembershipId, ...dto - }: TCreateUserPrivilegeDTO) => { + }) => { const projectMembership = await projectMembershipDAL.findById(projectMembershipId); if (!projectMembership) throw new NotFoundError({ message: `Project membership with ID ${projectMembershipId} found` }); @@ -147,14 +139,14 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ }; }; - const updateById = async ({ + const updateById: TProjectUserAdditionalPrivilegeServiceFactory["updateById"] = async ({ privilegeId, actorOrgId, actor, actorId, actorAuthMethod, ...dto - }: TUpdateUserPrivilegeDTO) => { + }) => { const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId); if (!userPrivilege) throw new NotFoundError({ message: `User additional privilege with ID ${privilegeId} not found` }); @@ -259,7 +251,13 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ }; }; - const deleteById = async ({ actorId, actor, actorOrgId, actorAuthMethod, privilegeId }: TDeleteUserPrivilegeDTO) => { + const deleteById: TProjectUserAdditionalPrivilegeServiceFactory["deleteById"] = async ({ + actorId, + actor, + actorOrgId, + actorAuthMethod, + privilegeId + }) => { const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId); if (!userPrivilege) throw new NotFoundError({ message: `User additional privilege with ID ${privilegeId} not found` }); @@ -299,13 +297,13 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ }; }; - const getPrivilegeDetailsById = async ({ + const getPrivilegeDetailsById: TProjectUserAdditionalPrivilegeServiceFactory["getPrivilegeDetailsById"] = async ({ privilegeId, actorOrgId, actor, actorId, actorAuthMethod - }: TGetUserPrivilegeDetailsDTO) => { + }) => { const userPrivilege = await projectUserAdditionalPrivilegeDAL.findById(privilegeId); if (!userPrivilege) throw new NotFoundError({ message: `User additional privilege with ID ${privilegeId} not found` }); @@ -335,13 +333,13 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ }; }; - const listPrivileges = async ({ + const listPrivileges: TProjectUserAdditionalPrivilegeServiceFactory["listPrivileges"] = async ({ projectMembershipId, actorOrgId, actor, actorId, actorAuthMethod - }: TListUserPrivilegesDTO) => { + }) => { const projectMembership = await projectMembershipDAL.findById(projectMembershipId); if (!projectMembership) throw new NotFoundError({ message: `Project membership with ID ${projectMembershipId} not found` }); diff --git a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-types.ts b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-types.ts index cfcf75872..a700d997d 100644 --- a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-types.ts +++ b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-types.ts @@ -1,3 +1,4 @@ +import { TProjectUserAdditionalPrivilege } from "@app/db/schemas"; import { TProjectPermission } from "@app/lib/types"; import { TProjectPermissionV2Schema } from "../permission/project-permission"; @@ -40,3 +41,20 @@ export type TDeleteUserPrivilegeDTO = Omit & { export type TGetUserPrivilegeDetailsDTO = Omit & { privilegeId: string }; export type TListUserPrivilegesDTO = Omit & { projectMembershipId: string }; + +interface TAdditionalPrivilege extends TProjectUserAdditionalPrivilege { + permissions: { + action: string[]; + subject?: string | undefined; + conditions?: unknown; + inverted?: boolean | undefined; + }[]; +} + +export type TProjectUserAdditionalPrivilegeServiceFactory = { + create: (arg: TCreateUserPrivilegeDTO) => Promise; + updateById: (arg: TUpdateUserPrivilegeDTO) => Promise; + deleteById: (arg: TDeleteUserPrivilegeDTO) => Promise; + getPrivilegeDetailsById: (arg: TGetUserPrivilegeDetailsDTO) => Promise; + listPrivileges: (arg: TListUserPrivilegesDTO) => Promise; +}; diff --git a/backend/src/ee/services/rate-limit/rate-limit-dal.ts b/backend/src/ee/services/rate-limit/rate-limit-dal.ts index 7279ff8ea..36b717cc4 100644 --- a/backend/src/ee/services/rate-limit/rate-limit-dal.ts +++ b/backend/src/ee/services/rate-limit/rate-limit-dal.ts @@ -1,7 +1,7 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TRateLimitDALFactory = ReturnType; +export type TRateLimitDALFactory = TOrmify; -export const rateLimitDALFactory = (db: TDbClient) => ormify(db, TableName.RateLimit, {}); +export const rateLimitDALFactory = (db: TDbClient): TRateLimitDALFactory => ormify(db, TableName.RateLimit, {}); diff --git a/backend/src/ee/services/rate-limit/rate-limit-service.ts b/backend/src/ee/services/rate-limit/rate-limit-service.ts index 61b18be91..730bb3b30 100644 --- a/backend/src/ee/services/rate-limit/rate-limit-service.ts +++ b/backend/src/ee/services/rate-limit/rate-limit-service.ts @@ -4,7 +4,7 @@ import { logger } from "@app/lib/logger"; import { TLicenseServiceFactory } from "../license/license-service"; import { TRateLimitDALFactory } from "./rate-limit-dal"; -import { RateLimitConfiguration, TRateLimit, TRateLimitUpdateDTO } from "./rate-limit-types"; +import { RateLimitConfiguration, TRateLimit, TRateLimitServiceFactory } from "./rate-limit-types"; let rateLimitMaxConfiguration: RateLimitConfiguration = { readLimit: 60, @@ -27,12 +27,13 @@ type TRateLimitServiceFactoryDep = { licenseService: Pick; }; -export type TRateLimitServiceFactory = ReturnType; - -export const rateLimitServiceFactory = ({ rateLimitDAL, licenseService }: TRateLimitServiceFactoryDep) => { +export const rateLimitServiceFactory = ({ + rateLimitDAL, + licenseService +}: TRateLimitServiceFactoryDep): TRateLimitServiceFactory => { const DEFAULT_RATE_LIMIT_CONFIG_ID = "00000000-0000-0000-0000-000000000000"; - const getRateLimits = async (): Promise => { + const getRateLimits: TRateLimitServiceFactory["getRateLimits"] = async () => { let rateLimit: TRateLimit; try { @@ -51,11 +52,11 @@ export const rateLimitServiceFactory = ({ rateLimitDAL, licenseService }: TRateL } }; - const updateRateLimit = async (updates: TRateLimitUpdateDTO): Promise => { + const updateRateLimit: TRateLimitServiceFactory["updateRateLimit"] = async (updates) => { return rateLimitDAL.updateById(DEFAULT_RATE_LIMIT_CONFIG_ID, updates); }; - const syncRateLimitConfiguration = async () => { + const syncRateLimitConfiguration: TRateLimitServiceFactory["syncRateLimitConfiguration"] = async () => { try { const rateLimit = await getRateLimits(); if (rateLimit) { @@ -78,7 +79,7 @@ export const rateLimitServiceFactory = ({ rateLimitDAL, licenseService }: TRateL } }; - const initializeBackgroundSync = async () => { + const initializeBackgroundSync: TRateLimitServiceFactory["initializeBackgroundSync"] = async () => { if (!licenseService.onPremFeatures.customRateLimits) { logger.info("Current license does not support custom rate limit configuration"); return; diff --git a/backend/src/ee/services/rate-limit/rate-limit-types.ts b/backend/src/ee/services/rate-limit/rate-limit-types.ts index d924dce51..0227afe08 100644 --- a/backend/src/ee/services/rate-limit/rate-limit-types.ts +++ b/backend/src/ee/services/rate-limit/rate-limit-types.ts @@ -1,3 +1,5 @@ +import { CronJob } from "cron"; + export type TRateLimitUpdateDTO = { readRateLimit: number; writeRateLimit: number; @@ -23,3 +25,10 @@ export type RateLimitConfiguration = { inviteUserRateLimit: number; mfaRateLimit: number; }; + +export type TRateLimitServiceFactory = { + getRateLimits: () => Promise; + updateRateLimit: (updates: TRateLimitUpdateDTO) => Promise; + initializeBackgroundSync: () => Promise | undefined>; + syncRateLimitConfiguration: () => Promise; +}; diff --git a/backend/src/ee/services/saml-config/saml-config-dal.ts b/backend/src/ee/services/saml-config/saml-config-dal.ts index c82adcb89..917b5c85c 100644 --- a/backend/src/ee/services/saml-config/saml-config-dal.ts +++ b/backend/src/ee/services/saml-config/saml-config-dal.ts @@ -1,10 +1,10 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TSamlConfigDALFactory = ReturnType; +export type TSamlConfigDALFactory = TOrmify; -export const samlConfigDALFactory = (db: TDbClient) => { +export const samlConfigDALFactory = (db: TDbClient): TSamlConfigDALFactory => { const samlCfgOrm = ormify(db, TableName.SamlConfig); return samlCfgOrm; diff --git a/backend/src/ee/services/saml-config/saml-config-service.ts b/backend/src/ee/services/saml-config/saml-config-service.ts index 601347862..c81fd518b 100644 --- a/backend/src/ee/services/saml-config/saml-config-service.ts +++ b/backend/src/ee/services/saml-config/saml-config-service.ts @@ -23,9 +23,9 @@ import { UserAliasType } from "@app/services/user-alias/user-alias-types"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TSamlConfigDALFactory } from "./saml-config-dal"; -import { TCreateSamlCfgDTO, TGetSamlCfgDTO, TSamlLoginDTO, TUpdateSamlCfgDTO } from "./saml-config-types"; +import { TSamlConfigServiceFactory } from "./saml-config-types"; type TSamlConfigServiceFactoryDep = { samlConfigDAL: Pick; @@ -47,8 +47,6 @@ type TSamlConfigServiceFactoryDep = { kmsService: Pick; }; -export type TSamlConfigServiceFactory = ReturnType; - export const samlConfigServiceFactory = ({ samlConfigDAL, orgDAL, @@ -61,8 +59,8 @@ export const samlConfigServiceFactory = ({ smtpService, identityMetadataDAL, kmsService -}: TSamlConfigServiceFactoryDep) => { - const createSamlCfg = async ({ +}: TSamlConfigServiceFactoryDep): TSamlConfigServiceFactory => { + const createSamlCfg: TSamlConfigServiceFactory["createSamlCfg"] = async ({ idpCert, actor, actorAuthMethod, @@ -73,7 +71,7 @@ export const samlConfigServiceFactory = ({ isActive, entryPoint, authProvider - }: TCreateSamlCfgDTO) => { + }) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Sso); @@ -101,7 +99,7 @@ export const samlConfigServiceFactory = ({ return samlConfig; }; - const updateSamlCfg = async ({ + const updateSamlCfg: TSamlConfigServiceFactory["updateSamlCfg"] = async ({ orgId, actor, actorOrgId, @@ -112,7 +110,7 @@ export const samlConfigServiceFactory = ({ isActive, entryPoint, authProvider - }: TUpdateSamlCfgDTO) => { + }) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Sso); const plan = await licenseService.getPlan(orgId); @@ -146,7 +144,7 @@ export const samlConfigServiceFactory = ({ return ssoConfig; }; - const getSaml = async (dto: TGetSamlCfgDTO) => { + const getSaml: TSamlConfigServiceFactory["getSaml"] = async (dto) => { let samlConfig: TSamlConfigs | undefined; if (dto.type === "org") { samlConfig = await samlConfigDAL.findOne({ orgId: dto.orgId }); @@ -221,7 +219,7 @@ export const samlConfigServiceFactory = ({ }; }; - const samlLogin = async ({ + const samlLogin: TSamlConfigServiceFactory["samlLogin"] = async ({ externalId, email, firstName, @@ -230,7 +228,7 @@ export const samlConfigServiceFactory = ({ orgId, relayState, metadata - }: TSamlLoginDTO) => { + }) => { const appCfg = getConfig(); const serverCfg = await getServerCfg(); diff --git a/backend/src/ee/services/saml-config/saml-config-types.ts b/backend/src/ee/services/saml-config/saml-config-types.ts index 444839a21..a9bd8f485 100644 --- a/backend/src/ee/services/saml-config/saml-config-types.ts +++ b/backend/src/ee/services/saml-config/saml-config-types.ts @@ -1,3 +1,4 @@ +import { TSamlConfigs } from "@app/db/schemas"; import { TOrgPermission } from "@app/lib/types"; import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type"; @@ -56,3 +57,26 @@ export type TSamlLoginDTO = { relayState?: string; metadata?: { key: string; value: string }[]; }; + +export type TSamlConfigServiceFactory = { + createSamlCfg: (arg: TCreateSamlCfgDTO) => Promise; + updateSamlCfg: (arg: TUpdateSamlCfgDTO) => Promise; + getSaml: (arg: TGetSamlCfgDTO) => Promise< + | { + id: string; + organization: string; + orgId: string; + authProvider: string; + isActive: boolean; + entryPoint: string; + issuer: string; + cert: string; + lastUsed: Date | null | undefined; + } + | undefined + >; + samlLogin: (arg: TSamlLoginDTO) => Promise<{ + isUserCompleted: boolean; + providerAuthToken: string; + }>; +}; diff --git a/backend/src/ee/services/scim/scim-dal.ts b/backend/src/ee/services/scim/scim-dal.ts index 05c21b80c..77a19d4d2 100644 --- a/backend/src/ee/services/scim/scim-dal.ts +++ b/backend/src/ee/services/scim/scim-dal.ts @@ -1,10 +1,10 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TScimDALFactory = ReturnType; +export type TScimDALFactory = TOrmify; -export const scimDALFactory = (db: TDbClient) => { +export const scimDALFactory = (db: TDbClient): TScimDALFactory => { const scimTokenOrm = ormify(db, TableName.ScimToken); return scimTokenOrm; }; diff --git a/backend/src/ee/services/scim/scim-service.ts b/backend/src/ee/services/scim/scim-service.ts index 4aad13ab8..6c5465488 100644 --- a/backend/src/ee/services/scim/scim-service.ts +++ b/backend/src/ee/services/scim/scim-service.ts @@ -11,7 +11,6 @@ import { TScimDALFactory } from "@app/ee/services/scim/scim-dal"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, NotFoundError, ScimRequestError, UnauthorizedError } from "@app/lib/errors"; import { alphaNumericNanoId } from "@app/lib/nanoid"; -import { TOrgPermission } from "@app/lib/types"; import { AuthTokenType } from "@app/services/auth/auth-type"; import { TExternalGroupOrgRoleMappingDALFactory } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-dal"; import { TGroupProjectDALFactory } from "@app/services/group-project/group-project-dal"; @@ -33,28 +32,10 @@ import { UserAliasType } from "@app/services/user-alias/user-alias-types"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { TProjectUserAdditionalPrivilegeDALFactory } from "../project-user-additional-privilege/project-user-additional-privilege-dal"; import { buildScimGroup, buildScimGroupList, buildScimUser, buildScimUserList, parseScimFilter } from "./scim-fns"; -import { - TCreateScimGroupDTO, - TCreateScimTokenDTO, - TCreateScimUserDTO, - TDeleteScimGroupDTO, - TDeleteScimTokenDTO, - TDeleteScimUserDTO, - TGetScimGroupDTO, - TGetScimUserDTO, - TListScimGroupsDTO, - TListScimUsers, - TListScimUsersDTO, - TReplaceScimUserDTO, - TScimGroup, - TScimTokenJwtPayload, - TUpdateScimGroupNamePatchDTO, - TUpdateScimGroupNamePutDTO, - TUpdateScimUserDTO -} from "./scim-types"; +import { TScimGroup, TScimServiceFactory } from "./scim-types"; type TScimServiceFactoryDep = { scimDAL: Pick; @@ -111,8 +92,6 @@ type TScimServiceFactoryDep = { externalGroupOrgRoleMappingDAL: TExternalGroupOrgRoleMappingDALFactory; }; -export type TScimServiceFactory = ReturnType; - export const scimServiceFactory = ({ licenseService, scimDAL, @@ -131,8 +110,8 @@ export const scimServiceFactory = ({ projectUserAdditionalPrivilegeDAL, smtpService, externalGroupOrgRoleMappingDAL -}: TScimServiceFactoryDep) => { - const createScimToken = async ({ +}: TScimServiceFactoryDep): TScimServiceFactory => { + const createScimToken: TScimServiceFactory["createScimToken"] = async ({ actor, actorId, actorOrgId, @@ -140,7 +119,7 @@ export const scimServiceFactory = ({ orgId, description, ttlDays - }: TCreateScimTokenDTO) => { + }) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Scim); @@ -169,7 +148,13 @@ export const scimServiceFactory = ({ return { scimToken }; }; - const listScimTokens = async ({ actor, actorId, actorOrgId, actorAuthMethod, orgId }: TOrgPermission) => { + const listScimTokens: TScimServiceFactory["listScimTokens"] = async ({ + actor, + actorId, + actorOrgId, + actorAuthMethod, + orgId + }) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Scim); @@ -183,7 +168,13 @@ export const scimServiceFactory = ({ return scimTokens; }; - const deleteScimToken = async ({ scimTokenId, actor, actorId, actorAuthMethod, actorOrgId }: TDeleteScimTokenDTO) => { + const deleteScimToken: TScimServiceFactory["deleteScimToken"] = async ({ + scimTokenId, + actor, + actorId, + actorAuthMethod, + actorOrgId + }) => { let scimToken = await scimDAL.findById(scimTokenId); if (!scimToken) throw new NotFoundError({ message: `SCIM token with ID '${scimTokenId}' not found` }); @@ -208,12 +199,12 @@ export const scimServiceFactory = ({ }; // SCIM server endpoints - const listScimUsers = async ({ + const listScimUsers: TScimServiceFactory["listScimUsers"] = async ({ startIndex = 0, limit = 100, filter, orgId - }: TListScimUsersDTO): Promise => { + }) => { const org = await orgDAL.findById(orgId); if (!org.scimEnabled) @@ -250,7 +241,7 @@ export const scimServiceFactory = ({ }); }; - const getScimUser = async ({ orgMembershipId, orgId }: TGetScimUserDTO) => { + const getScimUser: TScimServiceFactory["getScimUser"] = async ({ orgMembershipId, orgId }) => { const [membership] = await orgDAL .findMembership({ [`${TableName.OrgMembership}.id` as "id"]: orgMembershipId, @@ -287,7 +278,13 @@ export const scimServiceFactory = ({ }); }; - const createScimUser = async ({ externalId, email, firstName, lastName, orgId }: TCreateScimUserDTO) => { + const createScimUser: TScimServiceFactory["createScimUser"] = async ({ + externalId, + email, + firstName, + lastName, + orgId + }) => { if (!email) throw new ScimRequestError({ detail: "Invalid request. Missing email.", status: 400 }); const org = await orgDAL.findOrgById(orgId); @@ -467,7 +464,7 @@ export const scimServiceFactory = ({ }; // partial - const updateScimUser = async ({ orgMembershipId, orgId, operations }: TUpdateScimUserDTO) => { + const updateScimUser: TScimServiceFactory["updateScimUser"] = async ({ orgMembershipId, orgId, operations }) => { const org = await orgDAL.findOrgById(orgId); if (!org.orgAuthMethod) { throw new ScimRequestError({ @@ -540,7 +537,7 @@ export const scimServiceFactory = ({ return scimUser; }; - const replaceScimUser = async ({ + const replaceScimUser: TScimServiceFactory["replaceScimUser"] = async ({ orgMembershipId, active, orgId, @@ -548,7 +545,7 @@ export const scimServiceFactory = ({ firstName, email, externalId - }: TReplaceScimUserDTO) => { + }) => { const org = await orgDAL.findOrgById(orgId); if (!org.orgAuthMethod) { throw new ScimRequestError({ @@ -627,7 +624,7 @@ export const scimServiceFactory = ({ }); }; - const deleteScimUser = async ({ orgMembershipId, orgId }: TDeleteScimUserDTO) => { + const deleteScimUser: TScimServiceFactory["deleteScimUser"] = async ({ orgMembershipId, orgId }) => { const [membership] = await orgDAL.findMembership({ [`${TableName.OrgMembership}.id` as "id"]: orgMembershipId, [`${TableName.OrgMembership}.orgId` as "orgId"]: orgId @@ -660,7 +657,13 @@ export const scimServiceFactory = ({ return {}; // intentionally return empty object upon success }; - const listScimGroups = async ({ orgId, startIndex, limit, filter, isMembersExcluded }: TListScimGroupsDTO) => { + const listScimGroups: TScimServiceFactory["listScimGroups"] = async ({ + orgId, + startIndex, + limit, + filter, + isMembersExcluded + }) => { const plan = await licenseService.getPlan(orgId); if (!plan.groups) throw new BadRequestError({ @@ -768,7 +771,7 @@ export const scimServiceFactory = ({ ); }; - const createScimGroup = async ({ displayName, orgId, members }: TCreateScimGroupDTO) => { + const createScimGroup: TScimServiceFactory["createScimGroup"] = async ({ displayName, orgId, members }) => { const plan = await licenseService.getPlan(orgId); if (!plan.groups) throw new BadRequestError({ @@ -863,7 +866,7 @@ export const scimServiceFactory = ({ }); }; - const getScimGroup = async ({ groupId, orgId }: TGetScimGroupDTO) => { + const getScimGroup: TScimServiceFactory["getScimGroup"] = async ({ groupId, orgId }) => { const plan = await licenseService.getPlan(orgId); if (!plan.groups) throw new BadRequestError({ @@ -1011,7 +1014,12 @@ export const scimServiceFactory = ({ return updatedGroup; }; - const replaceScimGroup = async ({ groupId, orgId, displayName, members }: TUpdateScimGroupNamePutDTO) => { + const replaceScimGroup: TScimServiceFactory["replaceScimGroup"] = async ({ + groupId, + orgId, + displayName, + members + }) => { const plan = await licenseService.getPlan(orgId); if (!plan.groups) throw new BadRequestError({ @@ -1043,7 +1051,7 @@ export const scimServiceFactory = ({ }); }; - const updateScimGroup = async ({ groupId, orgId, operations }: TUpdateScimGroupNamePatchDTO) => { + const updateScimGroup: TScimServiceFactory["updateScimGroup"] = async ({ groupId, orgId, operations }) => { const plan = await licenseService.getPlan(orgId); if (!plan.groups) throw new BadRequestError({ @@ -1101,7 +1109,7 @@ export const scimServiceFactory = ({ }; }; - const deleteScimGroup = async ({ groupId, orgId }: TDeleteScimGroupDTO) => { + const deleteScimGroup: TScimServiceFactory["deleteScimGroup"] = async ({ groupId, orgId }) => { const plan = await licenseService.getPlan(orgId); if (!plan.groups) throw new BadRequestError({ @@ -1137,7 +1145,7 @@ export const scimServiceFactory = ({ return {}; // intentionally return empty object upon success }; - const fnValidateScimToken = async (token: TScimTokenJwtPayload) => { + const fnValidateScimToken: TScimServiceFactory["fnValidateScimToken"] = async (token) => { const scimToken = await scimDAL.findById(token.scimTokenId); if (!scimToken) throw new UnauthorizedError(); diff --git a/backend/src/ee/services/scim/scim-types.ts b/backend/src/ee/services/scim/scim-types.ts index 5099e4ca0..8bdea39e1 100644 --- a/backend/src/ee/services/scim/scim-types.ts +++ b/backend/src/ee/services/scim/scim-types.ts @@ -1,5 +1,6 @@ import { ScimPatchOperation } from "scim-patch"; +import { TScimTokens } from "@app/db/schemas"; import { TOrgPermission } from "@app/lib/types"; export type TCreateScimTokenDTO = { @@ -156,3 +157,47 @@ export type TScimGroup = { lastModified: Date; }; }; + +export type TScimServiceFactory = { + createScimToken: (arg: TCreateScimTokenDTO) => Promise<{ + scimToken: string; + }>; + listScimTokens: (arg: TOrgPermission) => Promise; + deleteScimToken: (arg: TDeleteScimTokenDTO) => Promise<{ + orgId: string; + id: string; + createdAt: Date; + updatedAt: Date; + description: string; + ttlDays: number; + }>; + listScimUsers: (arg: TListScimUsersDTO) => Promise; + getScimUser: (arg: TGetScimUserDTO) => Promise; + createScimUser: (arg: TCreateScimUserDTO) => Promise; + updateScimUser: (arg: TUpdateScimUserDTO) => Promise; + replaceScimUser: (arg: TReplaceScimUserDTO) => Promise; + deleteScimUser: (arg: TDeleteScimUserDTO) => Promise; + listScimGroups: (arg: TListScimGroupsDTO) => Promise; + createScimGroup: (arg: TCreateScimGroupDTO) => Promise; + getScimGroup: (arg: TGetScimGroupDTO) => Promise; + deleteScimGroup: (arg: TDeleteScimGroupDTO) => Promise; + replaceScimGroup: (arg: TUpdateScimGroupNamePutDTO) => Promise; + updateScimGroup: (arg: TUpdateScimGroupNamePatchDTO) => Promise<{ + members: { + value: string; + display: string; + }[]; + schemas: string[]; + id: string; + displayName: string; + meta: { + resourceType: string; + created: Date; + lastModified: Date; + }; + }>; + fnValidateScimToken: (token: TScimTokenJwtPayload) => Promise<{ + scimTokenId: string; + orgId: string; + }>; +}; diff --git a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts index 696caf311..c8df810ed 100644 --- a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts +++ b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import picomatch from "picomatch"; import { ActionProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { removeTrailingSlash } from "@app/lib/fn"; diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts index 0c276214a..e70d0af00 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts @@ -64,7 +64,7 @@ import { TUserDALFactory } from "@app/services/user/user-dal"; import { TLicenseServiceFactory } from "../license/license-service"; import { throwIfMissingSecretReadValueOrDescribePermission } from "../permission/permission-fns"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionSecretActions, ProjectPermissionSub } from "../permission/project-permission"; import { TSecretApprovalPolicyDALFactory } from "../secret-approval-policy/secret-approval-policy-dal"; import { TSecretSnapshotServiceFactory } from "../secret-snapshot/secret-snapshot-service"; diff --git a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-service.ts b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-service.ts index 986cb0ee4..c1b5b8c25 100644 --- a/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-service.ts +++ b/backend/src/ee/services/secret-rotation-v2/secret-rotation-v2-service.ts @@ -3,11 +3,10 @@ import { Knex } from "knex"; import isEqual from "lodash.isequal"; import { ActionProjectType, SecretType, TableName } from "@app/db/schemas"; -import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service"; -import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { hasSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionSecretActions, ProjectPermissionSecretRotationActions, diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts index 2364de79d..1099e17a7 100644 --- a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts +++ b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts @@ -14,7 +14,7 @@ import { TSecretFolderDALFactory } from "@app/services/secret-folder/secret-fold import { TSecretV2BridgeDALFactory } from "@app/services/secret-v2-bridge/secret-v2-bridge-dal"; import { TLicenseServiceFactory } from "../license/license-service"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionSecretActions, ProjectPermissionSecretRotationActions, diff --git a/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-queue.ts b/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-queue.ts index 3747af81f..aa8519027 100644 --- a/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-queue.ts +++ b/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-queue.ts @@ -1,8 +1,7 @@ import { join } from "path"; import { ProjectMembershipRole, TSecretScanningFindings } from "@app/db/schemas"; -import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service"; -import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types"; import { createTempFolder, deleteTempFolder, diff --git a/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-service.ts b/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-service.ts index 05449bd0d..34a981116 100644 --- a/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-service.ts +++ b/backend/src/ee/services/secret-scanning-v2/secret-scanning-v2-service.ts @@ -3,7 +3,7 @@ import { join } from "path"; import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionSecretScanningConfigActions, ProjectPermissionSecretScanningDataSourceActions, diff --git a/backend/src/ee/services/secret-scanning/secret-scanning-service.ts b/backend/src/ee/services/secret-scanning/secret-scanning-service.ts index 7d41091fc..1c12f8b4e 100644 --- a/backend/src/ee/services/secret-scanning/secret-scanning-service.ts +++ b/backend/src/ee/services/secret-scanning/secret-scanning-service.ts @@ -5,7 +5,7 @@ import { WebhookEventMap } from "@octokit/webhooks-types"; import { ProbotOctokit } from "probot"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { NotFoundError } from "@app/lib/errors"; diff --git a/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts b/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts index 8cae3dfb5..c9f6dac9d 100644 --- a/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts +++ b/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts @@ -28,7 +28,7 @@ import { hasSecretReadValueOrDescribePermission, throwIfMissingSecretReadValueOrDescribePermission } from "../permission/permission-fns"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSecretActions, diff --git a/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-service.ts b/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-service.ts index 6687efaf9..49d8c1ab6 100644 --- a/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-service.ts +++ b/backend/src/ee/services/ssh-certificate-template/ssh-certificate-template-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { ms } from "@app/lib/ms"; diff --git a/backend/src/ee/services/ssh-host-group/ssh-host-group-service.ts b/backend/src/ee/services/ssh-host-group/ssh-host-group-service.ts index 1137660d6..aa6d4f66a 100644 --- a/backend/src/ee/services/ssh-host-group/ssh-host-group-service.ts +++ b/backend/src/ee/services/ssh-host-group/ssh-host-group-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSshHostDALFactory } from "@app/ee/services/ssh-host/ssh-host-dal"; import { TSshHostLoginUserMappingDALFactory } from "@app/ee/services/ssh-host/ssh-host-login-user-mapping-dal"; diff --git a/backend/src/ee/services/ssh-host/ssh-host-service.ts b/backend/src/ee/services/ssh-host/ssh-host-service.ts index e41a8b403..64abfebbc 100644 --- a/backend/src/ee/services/ssh-host/ssh-host-service.ts +++ b/backend/src/ee/services/ssh-host/ssh-host-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import { ActionProjectType, ProjectType } from "@app/db/schemas"; import { TGroupDALFactory } from "@app/ee/services/group/group-dal"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionSshHostActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSshCertificateAuthorityDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-dal"; import { TSshCertificateAuthoritySecretDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-secret-dal"; diff --git a/backend/src/ee/services/ssh-host/ssh-host-types.ts b/backend/src/ee/services/ssh-host/ssh-host-types.ts index c0a780fbb..a8269ac37 100644 --- a/backend/src/ee/services/ssh-host/ssh-host-types.ts +++ b/backend/src/ee/services/ssh-host/ssh-host-types.ts @@ -1,6 +1,6 @@ import { Knex } from "knex"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { TSshHostLoginUserMappingDALFactory } from "@app/ee/services/ssh-host/ssh-host-login-user-mapping-dal"; import { TSshHostLoginUserDALFactory } from "@app/ee/services/ssh-host/ssh-login-user-dal"; import { TProjectPermission } from "@app/lib/types"; diff --git a/backend/src/ee/services/ssh/ssh-certificate-authority-service.ts b/backend/src/ee/services/ssh/ssh-certificate-authority-service.ts index d58644d90..6c35f0ddd 100644 --- a/backend/src/ee/services/ssh/ssh-certificate-authority-service.ts +++ b/backend/src/ee/services/ssh/ssh-certificate-authority-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSshCertificateAuthorityDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-dal"; import { TSshCertificateAuthoritySecretDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-secret-dal"; diff --git a/backend/src/ee/services/trusted-ip/trusted-ip-dal.ts b/backend/src/ee/services/trusted-ip/trusted-ip-dal.ts index e0c640be6..25998594a 100644 --- a/backend/src/ee/services/trusted-ip/trusted-ip-dal.ts +++ b/backend/src/ee/services/trusted-ip/trusted-ip-dal.ts @@ -1,10 +1,10 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; -import { ormify } from "@app/lib/knex"; +import { ormify, TOrmify } from "@app/lib/knex"; -export type TTrustedIpDALFactory = ReturnType; +export type TTrustedIpDALFactory = TOrmify; -export const trustedIpDALFactory = (db: TDbClient) => { +export const trustedIpDALFactory = (db: TDbClient): TTrustedIpDALFactory => { const trustedIpOrm = ormify(db, TableName.TrustedIps); return trustedIpOrm; }; diff --git a/backend/src/ee/services/trusted-ip/trusted-ip-service.ts b/backend/src/ee/services/trusted-ip/trusted-ip-service.ts index c407bdc82..6b9686e25 100644 --- a/backend/src/ee/services/trusted-ip/trusted-ip-service.ts +++ b/backend/src/ee/services/trusted-ip/trusted-ip-service.ts @@ -3,14 +3,13 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; import { BadRequestError } from "@app/lib/errors"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; -import { TProjectPermission } from "@app/lib/types"; import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TLicenseServiceFactory } from "../license/license-service"; -import { TPermissionServiceFactory } from "../permission/permission-service"; +import { TPermissionServiceFactory } from "../permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission"; import { TTrustedIpDALFactory } from "./trusted-ip-dal"; -import { TCreateIpDTO, TDeleteIpDTO, TUpdateIpDTO } from "./trusted-ip-types"; +import { TTrustedIpServiceFactory } from "./trusted-ip-types"; type TTrustedIpServiceFactoryDep = { trustedIpDAL: TTrustedIpDALFactory; @@ -19,15 +18,19 @@ type TTrustedIpServiceFactoryDep = { projectDAL: Pick; }; -export type TTrustedIpServiceFactory = ReturnType; - export const trustedIpServiceFactory = ({ trustedIpDAL, permissionService, licenseService, projectDAL -}: TTrustedIpServiceFactoryDep) => { - const listIpsByProjectId = async ({ projectId, actor, actorId, actorAuthMethod, actorOrgId }: TProjectPermission) => { +}: TTrustedIpServiceFactoryDep): TTrustedIpServiceFactory => { + const listIpsByProjectId: TTrustedIpServiceFactory["listIpsByProjectId"] = async ({ + projectId, + actor, + actorId, + actorAuthMethod, + actorOrgId + }) => { const { permission } = await permissionService.getProjectPermission({ actor, actorId, @@ -43,7 +46,7 @@ export const trustedIpServiceFactory = ({ return trustedIps; }; - const addProjectIp = async ({ + const addProjectIp: TTrustedIpServiceFactory["addProjectIp"] = async ({ projectId, actorId, actorAuthMethod, @@ -52,7 +55,7 @@ export const trustedIpServiceFactory = ({ ipAddress: ip, comment, isActive - }: TCreateIpDTO) => { + }) => { const { permission } = await permissionService.getProjectPermission({ actor, actorId, @@ -89,7 +92,7 @@ export const trustedIpServiceFactory = ({ return { trustedIp, project }; // for audit log }; - const updateProjectIp = async ({ + const updateProjectIp: TTrustedIpServiceFactory["updateProjectIp"] = async ({ projectId, actorId, actor, @@ -98,7 +101,7 @@ export const trustedIpServiceFactory = ({ ipAddress: ip, comment, trustedIpId - }: TUpdateIpDTO) => { + }) => { const { permission } = await permissionService.getProjectPermission({ actor, actorId, @@ -137,14 +140,14 @@ export const trustedIpServiceFactory = ({ return { trustedIp, project }; // for audit log }; - const deleteProjectIp = async ({ + const deleteProjectIp: TTrustedIpServiceFactory["deleteProjectIp"] = async ({ projectId, actorId, actor, actorOrgId, actorAuthMethod, trustedIpId - }: TDeleteIpDTO) => { + }) => { const { permission } = await permissionService.getProjectPermission({ actor, actorId, diff --git a/backend/src/ee/services/trusted-ip/trusted-ip-types.ts b/backend/src/ee/services/trusted-ip/trusted-ip-types.ts index abe066d65..2de94d22a 100644 --- a/backend/src/ee/services/trusted-ip/trusted-ip-types.ts +++ b/backend/src/ee/services/trusted-ip/trusted-ip-types.ts @@ -1,3 +1,4 @@ +import { TProjects, TTrustedIps } from "@app/db/schemas"; import { TProjectPermission } from "@app/lib/types"; export type TCreateIpDTO = TProjectPermission & { @@ -15,3 +16,19 @@ export type TUpdateIpDTO = TProjectPermission & { export type TDeleteIpDTO = TProjectPermission & { trustedIpId: string; }; + +export type TTrustedIpServiceFactory = { + listIpsByProjectId: (arg: TProjectPermission) => Promise; + addProjectIp: (arg: TCreateIpDTO) => Promise<{ + trustedIp: TTrustedIps; + project: TProjects; + }>; + updateProjectIp: (arg: TUpdateIpDTO) => Promise<{ + trustedIp: TTrustedIps; + project: TProjects; + }>; + deleteProjectIp: (arg: TDeleteIpDTO) => Promise<{ + trustedIp: TTrustedIps; + project: TProjects; + }>; +}; diff --git a/backend/src/keystore/keystore.ts b/backend/src/keystore/keystore.ts index d3f19168a..6a63af776 100644 --- a/backend/src/keystore/keystore.ts +++ b/backend/src/keystore/keystore.ts @@ -2,7 +2,7 @@ import { buildRedisFromConfig, TRedisConfigKeys } from "@app/lib/config/redis"; import { pgAdvisoryLockHashText } from "@app/lib/crypto/hashtext"; import { applyJitter } from "@app/lib/dates"; import { delay as delayMs } from "@app/lib/delay"; -import { Redlock, Settings } from "@app/lib/red-lock"; +import { ExecutionResult, Redlock, Settings } from "@app/lib/red-lock"; export const PgSqlLock = { BootUpMigration: 2023, @@ -14,8 +14,6 @@ export const PgSqlLock = { CreateProject: (orgId: string) => pgAdvisoryLockHashText(`create-project:${orgId}`) } as const; -export type TKeyStoreFactory = ReturnType; - // all the key prefixes used must be set here to avoid conflict export const KeyStorePrefixes = { SecretReplication: "secret-replication-import-lock", @@ -71,7 +69,28 @@ type TWaitTillReady = { jitter?: number; }; -export const keyStoreFactory = (redisConfigKeys: TRedisConfigKeys) => { +export type TKeyStoreFactory = { + setItem: (key: string, value: string | number | Buffer, prefix?: string) => Promise<"OK">; + getItem: (key: string, prefix?: string) => Promise; + setExpiry: (key: string, expiryInSeconds: number) => Promise; + setItemWithExpiry: ( + key: string, + expiryInSeconds: number | string, + value: string | number | Buffer, + prefix?: string + ) => Promise<"OK">; + deleteItem: (key: string) => Promise; + deleteItems: (arg: TDeleteItems) => Promise; + incrementBy: (key: string, value: number) => Promise; + acquireLock( + resources: string[], + duration: number, + settings?: Partial + ): Promise<{ release: () => Promise }>; + waitTillReady: ({ key, waitingCb, keyCheckCb, waitIteration, delay, jitter }: TWaitTillReady) => Promise; +}; + +export const keyStoreFactory = (redisConfigKeys: TRedisConfigKeys): TKeyStoreFactory => { const redis = buildRedisFromConfig(redisConfigKeys); const redisLock = new Redlock([redis], { retryCount: 2, retryDelay: 200 }); @@ -108,7 +127,6 @@ export const keyStoreFactory = (redisConfigKeys: TRedisConfigKeys) => { // eslint-disable-next-line no-await-in-loop await pipeline.exec(); totalDeleted += batch.length; - console.log("BATCH DONE"); // eslint-disable-next-line no-await-in-loop await delayMs(Math.max(0, applyJitter(delay, jitter))); diff --git a/backend/src/lib/knex/index.ts b/backend/src/lib/knex/index.ts index 5949afe33..090df561a 100644 --- a/backend/src/lib/knex/index.ts +++ b/backend/src/lib/knex/index.ts @@ -71,8 +71,8 @@ export const buildFindFilter = return bd; }; -export type TFindReturn = Array< - Awaited[0] & +export type TFindReturn = Array< + Tables[Tname]["base"] & (TCount extends true ? { count: string; @@ -94,40 +94,82 @@ export type TFindOpt< tx?: Knex; }; +export type TOrmify = { + transaction: (cb: (tx: Knex) => Promise) => Promise; + findById: (id: string, tx?: Knex) => Promise; + find: ( + filter: TFindFilter, + { offset, limit, sort, count, tx, countDistinct }?: TFindOpt + ) => Promise>; + findOne: (filter: Partial, tx?: Knex) => Promise; + create: (data: Tables[Tname]["insert"], tx?: Knex) => Promise; + insertMany: (data: readonly Tables[Tname]["insert"][], tx?: Knex) => Promise; + batchInsert: (data: readonly Tables[Tname]["insert"][], tx?: Knex) => Promise; + upsert: ( + data: readonly Tables[Tname]["insert"][], + onConflictField: keyof Tables[Tname]["base"] | Array, + tx?: Knex, + mergeColumns?: (keyof Knex.ResolveTableType, "update">)[] | undefined + ) => Promise; + updateById: ( + id: string, + { + $incr, + $decr, + ...data + }: Tables[Tname]["update"] & { + $incr?: { [x in keyof Partial]: number }; + $decr?: { [x in keyof Partial]: number }; + }, + tx?: Knex + ) => Promise; + update: ( + filter: TFindFilter, + { + $incr, + $decr, + ...data + }: Tables[Tname]["update"] & { + $incr?: { [x in keyof Partial]: number }; + $decr?: { [x in keyof Partial]: number }; + }, + tx?: Knex + ) => Promise; + deleteById: (id: string, tx?: Knex) => Promise; + countDocuments: (tx?: Knex) => Promise; + delete: (filter: TFindFilter, tx?: Knex) => Promise; +}; + // What is ormify // It is to inject typical operations like find, findOne, update, delete, create // This will avoid writing most common ones each time -export const ormify = (db: Knex, tableName: Tname, dal?: DbOps) => ({ +export const ormify = ( + db: Knex, + tableName: Tname, + dal?: DbOps +): TOrmify => ({ transaction: async (cb: (tx: Knex) => Promise) => db.transaction(async (trx) => { const res = await cb(trx); return res; }), - findById: async (id: string, tx?: Knex) => { + findById: async (id, tx): Promise => { try { const result = await (tx || db.replicaNode())(tableName) .where({ id } as never) .first("*"); - return result; + return result as Tables[Tname]["base"]; } catch (error) { throw new DatabaseError({ error, name: "Find by id" }); } }, - findOne: async (filter: Partial, tx?: Knex) => { - try { - const res = await (tx || db.replicaNode())(tableName).where(filter).first("*"); - return res; - } catch (error) { - throw new DatabaseError({ error, name: "Find one" }); - } - }, find: async < TCount extends boolean = false, TCountDistinct extends keyof Tables[Tname]["base"] | undefined = undefined >( filter: TFindFilter, { offset, limit, sort, count, tx, countDistinct }: TFindOpt = {} - ) => { + ): Promise> => { try { const query = (tx || db.replicaNode())(tableName).where(buildFindFilter(filter)); if (countDistinct) { @@ -142,35 +184,43 @@ export const ormify = (db: Kne void query.orderBy(sort.map(([column, order, nulls]) => ({ column: column as string, order, nulls }))); } - const res = (await query) as TFindReturn; - return res; + const res = await query; + return res as TFindReturn; } catch (error) { throw new DatabaseError({ error, name: "Find one" }); } }, - create: async (data: Tables[Tname]["insert"], tx?: Knex) => { + findOne: async (filter, tx): Promise => { + try { + const res = await (tx || db.replicaNode())(tableName).where(filter).first("*"); + return res as Tables[Tname]["base"]; + } catch (error) { + throw new DatabaseError({ error, name: "Find one" }); + } + }, + create: async (data, tx): Promise => { try { const [res] = await (tx || db)(tableName) .insert(data as never) .returning("*"); - return res; + return res as Tables[Tname]["base"]; } catch (error) { throw new DatabaseError({ error, name: "Create" }); } }, - insertMany: async (data: readonly Tables[Tname]["insert"][], tx?: Knex) => { + insertMany: async (data, tx?): Promise => { try { if (!data.length) return []; const res = await (tx || db)(tableName) .insert(data as never) .returning("*"); - return res; + return res as Tables[Tname]["base"][]; } catch (error) { throw new DatabaseError({ error, name: "Create" }); } }, // This spilit the insert into multiple chunk - batchInsert: async (data: readonly Tables[Tname]["insert"][], tx?: Knex) => { + batchInsert: async (data, tx): Promise => { try { if (!data.length) return []; const res = await (tx || db).batchInsert(tableName, data as never).returning("*"); @@ -179,12 +229,7 @@ export const ormify = (db: Kne throw new DatabaseError({ error, name: "batchInsert" }); } }, - upsert: async ( - data: readonly Tables[Tname]["insert"][], - onConflictField: keyof Tables[Tname]["base"] | Array, - tx?: Knex, - mergeColumns?: (keyof Knex.ResolveTableType, "update">)[] | undefined - ) => { + upsert: async (data, onConflictField, tx, mergeColumns): Promise => { try { if (!data.length) return []; const res = await (tx || db)(tableName) @@ -192,23 +237,12 @@ export const ormify = (db: Kne .onConflict(onConflictField as never) .merge(mergeColumns) .returning("*"); - return res; + return res as Tables[Tname]["base"][]; } catch (error) { throw new DatabaseError({ error, name: "Create" }); } }, - updateById: async ( - id: string, - { - $incr, - $decr, - ...data - }: Tables[Tname]["update"] & { - $incr?: { [x in keyof Partial]: number }; - $decr?: { [x in keyof Partial]: number }; - }, - tx?: Knex - ) => { + updateById: async (id, { $incr, $decr, ...data }, tx): Promise => { try { const query = (tx || db)(tableName) .where({ id } as never) @@ -225,23 +259,12 @@ export const ormify = (db: Kne }); } const [docs] = await query; - return docs; + return docs as Tables[Tname]["base"]; } catch (error) { throw new DatabaseError({ error, name: "Update by id" }); } }, - update: async ( - filter: TFindFilter, - { - $incr, - $decr, - ...data - }: Tables[Tname]["update"] & { - $incr?: { [x in keyof Partial]: number }; - $decr?: { [x in keyof Partial]: number }; - }, - tx?: Knex - ) => { + update: async (filter, { $incr, $decr, ...data }, tx): Promise => { try { const query = (tx || db)(tableName) .where(buildFindFilter(filter)) @@ -258,26 +281,34 @@ export const ormify = (db: Kne void query.increment(incrementField, incrementValue); }); } - return await query; + return (await query) as Tables[Tname]["base"][]; } catch (error) { throw new DatabaseError({ error, name: "Update" }); } }, - deleteById: async (id: string, tx?: Knex) => { + deleteById: async (id, tx): Promise => { try { const [res] = await (tx || db)(tableName) .where({ id } as never) .delete() .returning("*"); - return res; + return res as Tables[Tname]["base"]; } catch (error) { throw new DatabaseError({ error, name: "Delete by id" }); } }, - delete: async (filter: TFindFilter, tx?: Knex) => { + countDocuments: async (tx): Promise => { + try { + const [res] = await (tx || db)(tableName).count({ count: "*" }).returning("*"); + return Number((res as { count: number }).count || 0); + } catch (error) { + throw new DatabaseError({ error, name: "Delete by id" }); + } + }, + delete: async (filter, tx): Promise => { try { const res = await (tx || db)(tableName).where(buildFindFilter(filter)).delete().returning("*"); - return res; + return res as Tables[Tname]["base"][]; } catch (error) { throw new DatabaseError({ error, name: "Delete" }); } diff --git a/backend/src/queue/queue-service.ts b/backend/src/queue/queue-service.ts index 25677841d..16c5bb38f 100644 --- a/backend/src/queue/queue-service.ts +++ b/backend/src/queue/queue-service.ts @@ -325,11 +325,69 @@ const isQueueEnabled = (name: QueueName) => { } }; -export type TQueueServiceFactory = ReturnType; +export type TQueueServiceFactory = { + initialize: () => Promise; + start: ( + name: T, + jobFn: (job: Job, token?: string) => Promise, + queueSettings?: Omit + ) => void; + startPg: ( + jobName: QueueJobs, + jobsFn: (jobs: PgBoss.JobWithMetadata[]) => Promise, + options: WorkOptions & { + workerCount: number; + } + ) => Promise; + listen: < + T extends QueueName, + U extends keyof WorkerListener + >( + name: T, + event: U, + listener: WorkerListener[U] + ) => void; + queue: ( + name: T, + job: TQueueJobTypes[T]["name"], + data: TQueueJobTypes[T]["payload"], + opts?: JobsOptions & { + jobId?: string; + } + ) => Promise; + queuePg: ( + job: TQueueJobTypes[T]["name"], + data: TQueueJobTypes[T]["payload"], + opts?: PgBoss.SendOptions & { jobId?: string } + ) => Promise; + schedulePg: ( + job: TQueueJobTypes[T]["name"], + cron: string, + data: TQueueJobTypes[T]["payload"], + opts?: PgBoss.ScheduleOptions & { jobId?: string } + ) => Promise; + shutdown: () => Promise; + stopRepeatableJob: ( + name: T, + job: TQueueJobTypes[T]["name"], + repeatOpt: RepeatOptions, + jobId?: string + ) => Promise; + stopRepeatableJobByJobId: (name: T, jobId: string) => Promise; + stopRepeatableJobByKey: (name: T, repeatJobKey: string) => Promise; + clearQueue: (name: QueueName) => Promise; + stopJobById: (name: T, jobId: string) => Promise; + getRepeatableJobs: ( + name: QueueName, + startOffset?: number, + endOffset?: number + ) => Promise<{ key: string; name: string; id: string | null }[]>; +}; + export const queueServiceFactory = ( redisCfg: TRedisConfigKeys, { dbConnectionUrl, dbRootCert }: { dbConnectionUrl: string; dbRootCert?: string } -) => { +): TQueueServiceFactory => { const connection = buildRedisFromConfig(redisCfg); const queueContainer = {} as Record< QueueName, @@ -366,36 +424,26 @@ export const queueServiceFactory = ( }); }; - const start = ( - name: T, - jobFn: (job: Job, token?: string) => Promise, - queueSettings: Omit = {} - ) => { + const start: TQueueServiceFactory["start"] = (name, jobFn, queueSettings) => { if (queueContainer[name]) { throw new Error(`${name} queue is already initialized`); } - queueContainer[name] = new Queue(name as string, { + queueContainer[name] = new Queue(name as string, { ...queueSettings, connection }); const appCfg = getConfig(); if (appCfg.QUEUE_WORKERS_ENABLED && isQueueEnabled(name)) { - workerContainer[name] = new Worker(name, jobFn, { + workerContainer[name] = new Worker(name, jobFn, { ...queueSettings, connection }); } }; - const startPg = async ( - jobName: QueueJobs, - jobsFn: (jobs: PgBoss.JobWithMetadata[]) => Promise, - options: WorkOptions & { - workerCount: number; - } - ) => { + const startPg: TQueueServiceFactory["startPg"] = async (jobName, jobsFn, options) => { if (queueContainerPg[jobName]) { throw new Error(`${jobName} queue is already initialized`); } @@ -429,19 +477,12 @@ export const queueServiceFactory = ( await Promise.all( Array.from({ length: options.workerCount }).map(() => - pgBoss.work(jobName, { ...options, includeMetadata: true }, jobsFn) + pgBoss.work(jobName, { ...options, includeMetadata: true }, jobsFn) ) ); }; - const listen = < - T extends QueueName, - U extends keyof WorkerListener - >( - name: T, - event: U, - listener: WorkerListener[U] - ) => { + const listen: TQueueServiceFactory["listen"] = (name, event, listener) => { const appCfg = getConfig(); if (!appCfg.QUEUE_WORKERS_ENABLED || !isQueueEnabled(name)) { return; @@ -451,12 +492,7 @@ export const queueServiceFactory = ( worker.on(event, listener); }; - const queue = async ( - name: T, - job: TQueueJobTypes[T]["name"], - data: TQueueJobTypes[T]["payload"], - opts?: JobsOptions & { jobId?: string } - ) => { + const queue: TQueueServiceFactory["queue"] = async (name, job, data, opts) => { const q = queueContainer[name]; await q.add(job, data, opts); @@ -474,35 +510,25 @@ export const queueServiceFactory = ( }); }; - const schedulePg = async ( - job: TQueueJobTypes[T]["name"], - cron: string, - data: TQueueJobTypes[T]["payload"], - opts?: PgBoss.ScheduleOptions & { jobId?: string } - ) => { + const schedulePg: TQueueServiceFactory["schedulePg"] = async (job, cron, data, opts) => { await pgBoss.schedule(job, cron, data, opts); }; - const stopRepeatableJob = async ( - name: T, - job: TQueueJobTypes[T]["name"], - repeatOpt: RepeatOptions, - jobId?: string - ) => { + const stopRepeatableJob: TQueueServiceFactory["stopRepeatableJob"] = async (name, job, repeatOpt, jobId) => { const q = queueContainer[name]; if (q) { return q.removeRepeatable(job, repeatOpt, jobId); } }; - const getRepeatableJobs = (name: QueueName, startOffset?: number, endOffset?: number) => { + const getRepeatableJobs: TQueueServiceFactory["getRepeatableJobs"] = (name, startOffset, endOffset) => { const q = queueContainer[name]; if (!q) throw new Error(`Queue '${name}' not initialized`); return q.getRepeatableJobs(startOffset, endOffset); }; - const stopRepeatableJobByJobId = async (name: T, jobId: string) => { + const stopRepeatableJobByJobId: TQueueServiceFactory["stopRepeatableJobByJobId"] = async (name, jobId) => { const q = queueContainer[name]; const job = await q.getJob(jobId); if (!job) return true; @@ -511,23 +537,23 @@ export const queueServiceFactory = ( return q.removeRepeatableByKey(job.repeatJobKey); }; - const stopRepeatableJobByKey = async (name: T, repeatJobKey: string) => { + const stopRepeatableJobByKey: TQueueServiceFactory["stopRepeatableJobByKey"] = async (name, repeatJobKey) => { const q = queueContainer[name]; return q.removeRepeatableByKey(repeatJobKey); }; - const stopJobById = async (name: T, jobId: string) => { + const stopJobById: TQueueServiceFactory["stopJobById"] = async (name, jobId) => { const q = queueContainer[name]; const job = await q.getJob(jobId); return job?.remove().catch(() => undefined); }; - const clearQueue = async (name: QueueName) => { + const clearQueue: TQueueServiceFactory["clearQueue"] = async (name) => { const q = queueContainer[name]; await q.drain(); }; - const shutdown = async () => { + const shutdown: TQueueServiceFactory["shutdown"] = async () => { await Promise.all(Object.values(workerContainer).map((worker) => worker.close())); }; diff --git a/backend/src/services/app-connection/app-connection-service.ts b/backend/src/services/app-connection/app-connection-service.ts index 2ed97c8c5..c8e3271b4 100644 --- a/backend/src/services/app-connection/app-connection-service.ts +++ b/backend/src/services/app-connection/app-connection-service.ts @@ -5,7 +5,7 @@ import { ociConnectionService } from "@app/ee/services/app-connections/oci/oci-c import { ValidateOracleDBConnectionCredentialsSchema } from "@app/ee/services/app-connections/oracledb"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionAppConnectionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { generateHash } from "@app/lib/crypto/encryption"; import { DatabaseErrorCode } from "@app/lib/error-codes"; import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors"; diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index 64ba573d5..689228941 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -3,8 +3,7 @@ import jwt from "jsonwebtoken"; import { Knex } from "knex"; import { OrgMembershipRole, OrgMembershipStatus, TableName, TUsers, UserDeviceSchema } from "@app/db/schemas"; -import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service"; -import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types"; import { isAuthMethodSaml } from "@app/ee/services/permission/permission-fns"; import { getConfig } from "@app/lib/config/env"; import { request } from "@app/lib/config/request"; diff --git a/backend/src/services/certificate-authority/certificate-authority-service.ts b/backend/src/services/certificate-authority/certificate-authority-service.ts index a57c085ba..8a2aa0a5d 100644 --- a/backend/src/services/certificate-authority/certificate-authority-service.ts +++ b/backend/src/services/certificate-authority/certificate-authority-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType, ProjectType, TableName } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { OrgServiceActor } from "@app/lib/types"; diff --git a/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts b/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts index 083117241..98d9491f7 100644 --- a/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts +++ b/backend/src/services/certificate-authority/internal/internal-certificate-authority-service.ts @@ -12,7 +12,7 @@ import { TCertificateAuthorities, TCertificateTemplates } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionCertificateActions, diff --git a/backend/src/services/certificate-template/certificate-template-service.ts b/backend/src/services/certificate-template/certificate-template-service.ts index be1200503..4fa4e8283 100644 --- a/backend/src/services/certificate-template/certificate-template-service.ts +++ b/backend/src/services/certificate-template/certificate-template-service.ts @@ -4,7 +4,7 @@ import bcrypt from "bcrypt"; import { ActionProjectType, TCertificateTemplateEstConfigsUpdate } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionPkiTemplateActions, ProjectPermissionSub diff --git a/backend/src/services/certificate/certificate-service.ts b/backend/src/services/certificate/certificate-service.ts index 3921774fd..5558ccd65 100644 --- a/backend/src/services/certificate/certificate-service.ts +++ b/backend/src/services/certificate/certificate-service.ts @@ -4,7 +4,7 @@ import { createPrivateKey, createPublicKey, sign, verify } from "crypto"; import { ActionProjectType, ProjectType } from "@app/db/schemas"; import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionCertificateActions, ProjectPermissionSub diff --git a/backend/src/services/cmek/cmek-service.ts b/backend/src/services/cmek/cmek-service.ts index b968a8951..fd6cbf39d 100644 --- a/backend/src/services/cmek/cmek-service.ts +++ b/backend/src/services/cmek/cmek-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType, ProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionCmekActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { SigningAlgorithm } from "@app/lib/crypto/sign"; import { DatabaseErrorCode } from "@app/lib/error-codes"; diff --git a/backend/src/services/external-group-org-role-mapping/external-group-org-role-mapping-service.ts b/backend/src/services/external-group-org-role-mapping/external-group-org-role-mapping-service.ts index b38611419..de293609b 100644 --- a/backend/src/services/external-group-org-role-mapping/external-group-org-role-mapping-service.ts +++ b/backend/src/services/external-group-org-role-mapping/external-group-org-role-mapping-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { OrgServiceActor } from "@app/lib/types"; import { constructGroupOrgMembershipRoleMappings } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-fns"; import { TSyncExternalGroupOrgMembershipRoleMappingsDTO } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-types"; diff --git a/backend/src/services/external-migration/external-migration-service.ts b/backend/src/services/external-migration/external-migration-service.ts index 700819022..1a6d8ea11 100644 --- a/backend/src/services/external-migration/external-migration-service.ts +++ b/backend/src/services/external-migration/external-migration-service.ts @@ -1,5 +1,5 @@ import { OrgMembershipRole } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption"; import { ForbiddenRequestError } from "@app/lib/errors"; diff --git a/backend/src/services/folder-commit/folder-commit-service.ts b/backend/src/services/folder-commit/folder-commit-service.ts index 8c0bc8ebf..35f032312 100644 --- a/backend/src/services/folder-commit/folder-commit-service.ts +++ b/backend/src/services/folder-commit/folder-commit-service.ts @@ -9,7 +9,7 @@ import { TSecretV2TagJunctionInsert, TSecretVersionsV2 } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionCommitsActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors"; diff --git a/backend/src/services/group-project/group-project-service.ts b/backend/src/services/group-project/group-project-service.ts index a793ecfab..47d8950cc 100644 --- a/backend/src/services/group-project/group-project-service.ts +++ b/backend/src/services/group-project/group-project-service.ts @@ -6,7 +6,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionGroupActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { decryptAsymmetric, encryptAsymmetric } from "@app/lib/crypto"; import { infisicalSymmetricDecrypt } from "@app/lib/crypto/encryption"; diff --git a/backend/src/services/identity-alicloud-auth/identity-alicloud-auth-service.ts b/backend/src/services/identity-alicloud-auth/identity-alicloud-auth-service.ts index ad357b4e9..77ae64121 100644 --- a/backend/src/services/identity-alicloud-auth/identity-alicloud-auth-service.ts +++ b/backend/src/services/identity-alicloud-auth/identity-alicloud-auth-service.ts @@ -10,7 +10,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { request } from "@app/lib/config/request"; import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedError } from "@app/lib/errors"; diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts index d6236e4ed..b60366335 100644 --- a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts @@ -11,7 +11,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedError } from "@app/lib/errors"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; diff --git a/backend/src/services/identity-azure-auth/identity-azure-auth-service.ts b/backend/src/services/identity-azure-auth/identity-azure-auth-service.ts index 5baa00652..4c0d2164b 100644 --- a/backend/src/services/identity-azure-auth/identity-azure-auth-service.ts +++ b/backend/src/services/identity-azure-auth/identity-azure-auth-service.ts @@ -8,7 +8,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedError } from "@app/lib/errors"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; diff --git a/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts b/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts index 7420b61cf..1e21d1d3e 100644 --- a/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts +++ b/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts @@ -8,7 +8,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedError } from "@app/lib/errors"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; diff --git a/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts b/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts index 39fc28ad2..7ebf75a85 100644 --- a/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts +++ b/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts @@ -10,7 +10,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, diff --git a/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts b/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts index 1f89745a9..3ce28361f 100644 --- a/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts +++ b/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts @@ -17,7 +17,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedError } from "@app/lib/errors"; import { GatewayHttpProxyActions, GatewayProxyProtocol, withGatewayProxy } from "@app/lib/gateway"; diff --git a/backend/src/services/identity-ldap-auth/identity-ldap-auth-service.ts b/backend/src/services/identity-ldap-auth/identity-ldap-auth-service.ts index 7462c9228..89a169b1a 100644 --- a/backend/src/services/identity-ldap-auth/identity-ldap-auth-service.ts +++ b/backend/src/services/identity-ldap-auth/identity-ldap-auth-service.ts @@ -10,7 +10,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; diff --git a/backend/src/services/identity-oci-auth/identity-oci-auth-service.ts b/backend/src/services/identity-oci-auth/identity-oci-auth-service.ts index 00e3884bd..106c30486 100644 --- a/backend/src/services/identity-oci-auth/identity-oci-auth-service.ts +++ b/backend/src/services/identity-oci-auth/identity-oci-auth-service.ts @@ -11,7 +11,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { request } from "@app/lib/config/request"; import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedError } from "@app/lib/errors"; diff --git a/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts b/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts index d54a49f38..211d00163 100644 --- a/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts +++ b/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts @@ -11,7 +11,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, diff --git a/backend/src/services/identity-project/identity-project-service.ts b/backend/src/services/identity-project/identity-project-service.ts index 14df0cd4a..81387d141 100644 --- a/backend/src/services/identity-project/identity-project-service.ts +++ b/backend/src/services/identity-project/identity-project-service.ts @@ -5,7 +5,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors"; import { groupBy } from "@app/lib/fn"; diff --git a/backend/src/services/identity-token-auth/identity-token-auth-service.ts b/backend/src/services/identity-token-auth/identity-token-auth-service.ts index 549512452..8f1218045 100644 --- a/backend/src/services/identity-token-auth/identity-token-auth-service.ts +++ b/backend/src/services/identity-token-auth/identity-token-auth-service.ts @@ -8,7 +8,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; diff --git a/backend/src/services/identity-ua/identity-ua-service.ts b/backend/src/services/identity-ua/identity-ua-service.ts index dec172e4e..eaae0150b 100644 --- a/backend/src/services/identity-ua/identity-ua-service.ts +++ b/backend/src/services/identity-ua/identity-ua-service.ts @@ -11,7 +11,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedError } from "@app/lib/errors"; import { checkIPAgainstBlocklist, extractIPDetails, isValidIpOrCidr, TIp } from "@app/lib/ip"; diff --git a/backend/src/services/identity/identity-service.ts b/backend/src/services/identity/identity-service.ts index fd893713e..3ffee698a 100644 --- a/backend/src/services/identity/identity-service.ts +++ b/backend/src/services/identity/identity-service.ts @@ -7,7 +7,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors"; import { TIdentityProjectDALFactory } from "@app/services/identity-project/identity-project-dal"; diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index eb17c05bb..2517c040c 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -11,7 +11,7 @@ import { TIntegrationAuths, TIntegrationAuthsInsert } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; import { request } from "@app/lib/config/request"; diff --git a/backend/src/services/integration/integration-service.ts b/backend/src/services/integration/integration-service.ts index ad08e89d1..2ef8615eb 100644 --- a/backend/src/services/integration/integration-service.ts +++ b/backend/src/services/integration/integration-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSecretActions, diff --git a/backend/src/services/microsoft-teams/microsoft-teams-service.ts b/backend/src/services/microsoft-teams/microsoft-teams-service.ts index 1413a3199..23ed61402 100644 --- a/backend/src/services/microsoft-teams/microsoft-teams-service.ts +++ b/backend/src/services/microsoft-teams/microsoft-teams-service.ts @@ -10,7 +10,7 @@ import { CronJob } from "cron"; import { FastifyReply, FastifyRequest } from "fastify"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; diff --git a/backend/src/services/org-admin/org-admin-service.ts b/backend/src/services/org-admin/org-admin-service.ts index 5f9e25f29..cb161c7e5 100644 --- a/backend/src/services/org-admin/org-admin-service.ts +++ b/backend/src/services/org-admin/org-admin-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { ProjectMembershipRole, ProjectVersion, SecretKeyEncoding } from "@app/db/schemas"; import { OrgPermissionAdminConsoleAction, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { infisicalSymmetricDecrypt } from "@app/lib/crypto/encryption"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; diff --git a/backend/src/services/org/org-role-service.ts b/backend/src/services/org/org-role-service.ts index 1243055eb..6ce2b22cd 100644 --- a/backend/src/services/org/org-role-service.ts +++ b/backend/src/services/org/org-role-service.ts @@ -9,7 +9,7 @@ import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { TExternalGroupOrgRoleMappingDALFactory } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-dal"; import { TOrgDALFactory } from "@app/services/org/org-dal"; diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index 031b906a6..1215b7c00 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -29,7 +29,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TProjectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal"; import { TSamlConfigDALFactory } from "@app/ee/services/saml-config/saml-config-dal"; diff --git a/backend/src/services/pki-alert/pki-alert-service.ts b/backend/src/services/pki-alert/pki-alert-service.ts index 0ddc0f3ae..946740b66 100644 --- a/backend/src/services/pki-alert/pki-alert-service.ts +++ b/backend/src/services/pki-alert/pki-alert-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType, ProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { groupBy } from "@app/lib/fn"; diff --git a/backend/src/services/pki-collection/pki-collection-service.ts b/backend/src/services/pki-collection/pki-collection-service.ts index 577441bfb..8d758b5e9 100644 --- a/backend/src/services/pki-collection/pki-collection-service.ts +++ b/backend/src/services/pki-collection/pki-collection-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType, ProjectType, TPkiCollectionItems } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal"; diff --git a/backend/src/services/pki-subscriber/pki-subscriber-queue.ts b/backend/src/services/pki-subscriber/pki-subscriber-queue.ts index 28b9353b7..c9f0d7797 100644 --- a/backend/src/services/pki-subscriber/pki-subscriber-queue.ts +++ b/backend/src/services/pki-subscriber/pki-subscriber-queue.ts @@ -1,5 +1,4 @@ -import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service"; -import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types"; import { logger } from "@app/lib/logger"; import { QueueJobs, QueueName, TQueueServiceFactory } from "@app/queue"; diff --git a/backend/src/services/pki-subscriber/pki-subscriber-service.ts b/backend/src/services/pki-subscriber/pki-subscriber-service.ts index 5bedbd60c..a3e6ec78c 100644 --- a/backend/src/services/pki-subscriber/pki-subscriber-service.ts +++ b/backend/src/services/pki-subscriber/pki-subscriber-service.ts @@ -4,7 +4,7 @@ import * as x509 from "@peculiar/x509"; import { ActionProjectType } from "@app/db/schemas"; import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionCertificateActions, ProjectPermissionPkiSubscriberActions, diff --git a/backend/src/services/pki-templates/pki-templates-dal.ts b/backend/src/services/pki-templates/pki-templates-dal.ts index 45c632d70..81fffb0e8 100644 --- a/backend/src/services/pki-templates/pki-templates-dal.ts +++ b/backend/src/services/pki-templates/pki-templates-dal.ts @@ -4,7 +4,7 @@ import { Tables } from "knex/types/tables"; import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; -import { buildFindFilter, ormify, selectAllTableCols, TFindFilter, TFindOpt, TFindReturn } from "@app/lib/knex"; +import { buildFindFilter, ormify, selectAllTableCols, TFindFilter, TFindOpt } from "@app/lib/knex"; export type TPkiTemplatesDALFactory = ReturnType; @@ -91,7 +91,7 @@ export const pkiTemplatesDALFactory = (db: TDbClient) => { void query.orderBy(sort.map(([column, order, nulls]) => ({ column: column as string, order, nulls }))); } - const res = (await query) as TFindReturn; + const res = (await query) as Array[0] & { count: string }>; return res.map((el) => ({ ...el, ca: { id: el.caId, name: el.caName } })); } catch (error) { throw new DatabaseError({ error, name: "Find one" }); diff --git a/backend/src/services/pki-templates/pki-templates-service.ts b/backend/src/services/pki-templates/pki-templates-service.ts index 97f910d6e..e648ab88f 100644 --- a/backend/src/services/pki-templates/pki-templates-service.ts +++ b/backend/src/services/pki-templates/pki-templates-service.ts @@ -5,7 +5,7 @@ import RE2 from "re2"; import { ActionProjectType } from "@app/db/schemas"; import { TCertificateAuthorityCrlDALFactory } from "@app/ee/services/certificate-authority-crl/certificate-authority-crl-dal"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionPkiTemplateActions, ProjectPermissionSub diff --git a/backend/src/services/project-bot/project-bot-service.ts b/backend/src/services/project-bot/project-bot-service.ts index dc69cbf99..7dc5b058e 100644 --- a/backend/src/services/project-bot/project-bot-service.ts +++ b/backend/src/services/project-bot/project-bot-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType, ProjectVersion } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { generateAsymmetricKeyPair } from "@app/lib/crypto"; import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption"; diff --git a/backend/src/services/project-env/project-env-service.ts b/backend/src/services/project-env/project-env-service.ts index f9935df54..9a82a6bbe 100644 --- a/backend/src/services/project-env/project-env-service.ts +++ b/backend/src/services/project-env/project-env-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; diff --git a/backend/src/services/project-key/project-key-service.ts b/backend/src/services/project-key/project-key-service.ts index 8ce2569a0..a884d25bc 100644 --- a/backend/src/services/project-key/project-key-service.ts +++ b/backend/src/services/project-key/project-key-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError } from "@app/lib/errors"; diff --git a/backend/src/services/project-membership/project-membership-service.ts b/backend/src/services/project-membership/project-membership-service.ts index a68a690d3..b9e502922 100644 --- a/backend/src/services/project-membership/project-membership-service.ts +++ b/backend/src/services/project-membership/project-membership-service.ts @@ -7,7 +7,7 @@ import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TProjectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal"; import { getConfig } from "@app/lib/config/env"; diff --git a/backend/src/services/project-role/project-role-service.ts b/backend/src/services/project-role/project-role-service.ts index babcf7d9c..dd0eecc68 100644 --- a/backend/src/services/project-role/project-role-service.ts +++ b/backend/src/services/project-role/project-role-service.ts @@ -3,7 +3,7 @@ import { PackRule, packRules, unpackRules } from "@casl/ability/extra"; import { requestContext } from "@fastify/request-context"; import { ActionProjectType, ProjectMembershipRole, ProjectType, TableName, TProjects } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSet, diff --git a/backend/src/services/project/project-service.ts b/backend/src/services/project/project-service.ts index 680b0187c..370db9405 100644 --- a/backend/src/services/project/project-service.ts +++ b/backend/src/services/project/project-service.ts @@ -12,7 +12,7 @@ import { import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionCertificateActions, @@ -22,8 +22,10 @@ import { ProjectPermissionSshHostActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; -import { TProjectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-service"; -import { InfisicalProjectTemplate } from "@app/ee/services/project-template/project-template-types"; +import { + InfisicalProjectTemplate, + TProjectTemplateServiceFactory +} from "@app/ee/services/project-template/project-template-types"; import { TSshCertificateAuthorityDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-dal"; import { TSshCertificateAuthoritySecretDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-secret-dal"; import { TSshCertificateDALFactory } from "@app/ee/services/ssh-certificate/ssh-certificate-dal"; diff --git a/backend/src/services/secret-blind-index/secret-blind-index-service.ts b/backend/src/services/secret-blind-index/secret-blind-index-service.ts index 1cbbbcbb8..a19ce8b88 100644 --- a/backend/src/services/secret-blind-index/secret-blind-index-service.ts +++ b/backend/src/services/secret-blind-index/secret-blind-index-service.ts @@ -1,5 +1,5 @@ import { ActionProjectType, ProjectMembershipRole } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { TSecretDALFactory } from "../secret/secret-dal"; diff --git a/backend/src/services/secret-folder/secret-folder-service.ts b/backend/src/services/secret-folder/secret-folder-service.ts index 5722734f8..d6007957b 100644 --- a/backend/src/services/secret-folder/secret-folder-service.ts +++ b/backend/src/services/secret-folder/secret-folder-service.ts @@ -3,7 +3,7 @@ import path from "path"; import { v4 as uuidv4, validate as uuidValidate } from "uuid"; import { ActionProjectType, TSecretFoldersInsert } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; diff --git a/backend/src/services/secret-import/secret-import-service.ts b/backend/src/services/secret-import/secret-import-service.ts index 5078496d6..403484fc2 100644 --- a/backend/src/services/secret-import/secret-import-service.ts +++ b/backend/src/services/secret-import/secret-import-service.ts @@ -8,7 +8,7 @@ import { hasSecretReadValueOrDescribePermission, throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSecretActions, diff --git a/backend/src/services/secret-sharing/secret-sharing-service.ts b/backend/src/services/secret-sharing/secret-sharing-service.ts index 24739b01b..e879d56f1 100644 --- a/backend/src/services/secret-sharing/secret-sharing-service.ts +++ b/backend/src/services/secret-sharing/secret-sharing-service.ts @@ -3,7 +3,7 @@ import crypto from "node:crypto"; import bcrypt from "bcrypt"; import { TSecretSharing } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; diff --git a/backend/src/services/secret-sync/secret-sync-queue.ts b/backend/src/services/secret-sync/secret-sync-queue.ts index 66e83661f..a8ff94e82 100644 --- a/backend/src/services/secret-sync/secret-sync-queue.ts +++ b/backend/src/services/secret-sync/secret-sync-queue.ts @@ -3,8 +3,7 @@ import { AxiosError } from "axios"; import { Job } from "bullmq"; import { ProjectMembershipRole, SecretType } from "@app/db/schemas"; -import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service"; -import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore"; import { getConfig } from "@app/lib/config/env"; diff --git a/backend/src/services/secret-sync/secret-sync-service.ts b/backend/src/services/secret-sync/secret-sync-service.ts index e7751d3f9..b64620827 100644 --- a/backend/src/services/secret-sync/secret-sync-service.ts +++ b/backend/src/services/secret-sync/secret-sync-service.ts @@ -3,7 +3,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionSecretActions, ProjectPermissionSecretSyncActions, diff --git a/backend/src/services/secret-tag/secret-tag-service.ts b/backend/src/services/secret-tag/secret-tag-service.ts index 0a154a4be..8a08c44dd 100644 --- a/backend/src/services/secret-tag/secret-tag-service.ts +++ b/backend/src/services/secret-tag/secret-tag-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts index 1adfac22c..01718d570 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts @@ -561,7 +561,7 @@ const formatMultiValueEnv = (val?: string) => { return `"${val.replaceAll("\n", "\\n")}"`; }; -type TSecretReferenceTraceNode = { +export type TSecretReferenceTraceNode = { key: string; value?: string; environment: string; diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts index c4b5835c4..fc758b4f5 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts @@ -14,7 +14,7 @@ import { hasSecretReadValueOrDescribePermission, throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionCommitsActions, diff --git a/backend/src/services/secret/secret-fns.ts b/backend/src/services/secret/secret-fns.ts index 96f89ab5f..847ef17df 100644 --- a/backend/src/services/secret/secret-fns.ts +++ b/backend/src/services/secret/secret-fns.ts @@ -13,7 +13,7 @@ import { TSecrets } from "@app/db/schemas"; import { hasSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionSecretActions } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; import { diff --git a/backend/src/services/secret/secret-queue.ts b/backend/src/services/secret/secret-queue.ts index e9c6f2d88..25b6e6572 100644 --- a/backend/src/services/secret/secret-queue.ts +++ b/backend/src/services/secret/secret-queue.ts @@ -11,8 +11,7 @@ import { TSecretSnapshotSecretsV2, TSecretVersionsV2 } from "@app/db/schemas"; -import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service"; -import { Actor, EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { Actor, EventType, TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-types"; import { TSecretApprovalRequestDALFactory } from "@app/ee/services/secret-approval-request/secret-approval-request-dal"; import { TSecretRotationDALFactory } from "@app/ee/services/secret-rotation/secret-rotation-dal"; import { TSnapshotDALFactory } from "@app/ee/services/secret-snapshot/snapshot-dal"; diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index 4fa7404d3..d5c836ff7 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -17,7 +17,7 @@ import { hasSecretReadValueOrDescribePermission, throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSecretActions, diff --git a/backend/src/services/service-token/service-token-service.ts b/backend/src/services/service-token/service-token-service.ts index bbd306bb5..d68b48d78 100644 --- a/backend/src/services/service-token/service-token-service.ts +++ b/backend/src/services/service-token/service-token-service.ts @@ -4,7 +4,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import bcrypt from "bcrypt"; import { ActionProjectType } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSecretActions, diff --git a/backend/src/services/slack/slack-service.ts b/backend/src/services/slack/slack-service.ts index 9c1460c37..c8aa8aaf6 100644 --- a/backend/src/services/slack/slack-service.ts +++ b/backend/src/services/slack/slack-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { InstallProvider } from "@slack/oauth"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; diff --git a/backend/src/services/user/user-service.ts b/backend/src/services/user/user-service.ts index 0f6ae3bf8..07d55f787 100644 --- a/backend/src/services/user/user-service.ts +++ b/backend/src/services/user/user-service.ts @@ -2,7 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { SecretKeyEncoding } from "@app/db/schemas"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { infisicalSymmetricDecrypt } from "@app/lib/crypto/encryption"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; diff --git a/backend/src/services/webhook/webhook-fns.ts b/backend/src/services/webhook/webhook-fns.ts index 6729e9a37..d5fc9f5b8 100644 --- a/backend/src/services/webhook/webhook-fns.ts +++ b/backend/src/services/webhook/webhook-fns.ts @@ -4,8 +4,7 @@ import { AxiosError } from "axios"; import picomatch from "picomatch"; import { TWebhooks } from "@app/db/schemas"; -import { TAuditLogServiceFactory } from "@app/ee/services/audit-log/audit-log-service"; -import { EventType, WebhookTriggeredEvent } from "@app/ee/services/audit-log/audit-log-types"; +import { EventType, TAuditLogServiceFactory, WebhookTriggeredEvent } from "@app/ee/services/audit-log/audit-log-types"; import { request } from "@app/lib/config/request"; import { NotFoundError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; diff --git a/backend/src/services/webhook/webhook-service.ts b/backend/src/services/webhook/webhook-service.ts index c555dc8d1..eb58ee5bd 100644 --- a/backend/src/services/webhook/webhook-service.ts +++ b/backend/src/services/webhook/webhook-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { ActionProjectType, TWebhooksInsert } from "@app/db/schemas"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { NotFoundError } from "@app/lib/errors"; diff --git a/backend/src/services/workflow-integration/workflow-integration-service.ts b/backend/src/services/workflow-integration/workflow-integration-service.ts index 41419061b..cb7f7a325 100644 --- a/backend/src/services/workflow-integration/workflow-integration-service.ts +++ b/backend/src/services/workflow-integration/workflow-integration-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; +import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { TWorkflowIntegrationDALFactory } from "./workflow-integration-dal"; import { TGetWorkflowIntegrationsByOrg } from "./workflow-integration-types";