diff --git a/backend/.prettierrc.json b/backend/.prettierrc.json index f9058accf..987f567d4 100644 --- a/backend/.prettierrc.json +++ b/backend/.prettierrc.json @@ -1,7 +1,7 @@ { "singleQuote": false, - "printWidth": 100, + "printWidth": 120, "trailingComma": "none", "tabWidth": 2, "semi": true -} \ No newline at end of file +} diff --git a/backend/src/@types/fastify-zod.d.ts b/backend/src/@types/fastify-zod.d.ts index cff119c2f..393579391 100644 --- a/backend/src/@types/fastify-zod.d.ts +++ b/backend/src/@types/fastify-zod.d.ts @@ -1,9 +1,4 @@ -import { - FastifyInstance, - RawReplyDefaultExpression, - RawRequestDefaultExpression, - RawServerDefault -} from "fastify"; +import { FastifyInstance, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerDefault } from "fastify"; import { Logger } from "pino"; import { ZodTypeProvider } from "@app/server/plugins/fastify-zod"; diff --git a/backend/src/@types/knex.d.ts b/backend/src/@types/knex.d.ts index 05ce1e59d..5bf563810 100644 --- a/backend/src/@types/knex.d.ts +++ b/backend/src/@types/knex.d.ts @@ -177,11 +177,7 @@ declare module "knex/types/tables" { TUserEncryptionKeysInsert, TUserEncryptionKeysUpdate >; - [TableName.AuthTokens]: Knex.CompositeTableType< - TAuthTokens, - TAuthTokensInsert, - TAuthTokensUpdate - >; + [TableName.AuthTokens]: Knex.CompositeTableType; [TableName.AuthTokenSession]: Knex.CompositeTableType< TAuthTokenSessions, TAuthTokenSessionsInsert, @@ -192,32 +188,16 @@ declare module "knex/types/tables" { TBackupPrivateKeyInsert, TBackupPrivateKeyUpdate >; - [TableName.Organization]: Knex.CompositeTableType< - TOrganizations, - TOrganizationsInsert, - TOrganizationsUpdate - >; - [TableName.OrgMembership]: Knex.CompositeTableType< - TOrgMemberships, - TOrgMembershipsInsert, - TOrgMembershipsUpdate - >; + [TableName.Organization]: Knex.CompositeTableType; + [TableName.OrgMembership]: Knex.CompositeTableType; [TableName.OrgRoles]: Knex.CompositeTableType; [TableName.IncidentContact]: Knex.CompositeTableType< TIncidentContacts, TIncidentContactsInsert, TIncidentContactsUpdate >; - [TableName.UserAction]: Knex.CompositeTableType< - TUserActions, - TUserActionsInsert, - TUserActionsUpdate - >; - [TableName.SuperAdmin]: Knex.CompositeTableType< - TSuperAdmin, - TSuperAdminInsert, - TSuperAdminUpdate - >; + [TableName.UserAction]: Knex.CompositeTableType; + [TableName.SuperAdmin]: Knex.CompositeTableType; [TableName.ApiKey]: Knex.CompositeTableType; [TableName.Project]: Knex.CompositeTableType; [TableName.ProjectMembership]: Knex.CompositeTableType< @@ -230,73 +210,33 @@ declare module "knex/types/tables" { TProjectEnvironmentsInsert, TProjectEnvironmentsUpdate >; - [TableName.ProjectBot]: Knex.CompositeTableType< - TProjectBots, - TProjectBotsInsert, - TProjectBotsUpdate - >; - [TableName.ProjectRoles]: Knex.CompositeTableType< - TProjectRoles, - TProjectRolesInsert, - TProjectRolesUpdate - >; - [TableName.ProjectKeys]: Knex.CompositeTableType< - TProjectKeys, - TProjectKeysInsert, - TProjectKeysUpdate - >; + [TableName.ProjectBot]: Knex.CompositeTableType; + [TableName.ProjectRoles]: Knex.CompositeTableType; + [TableName.ProjectKeys]: Knex.CompositeTableType; [TableName.Secret]: Knex.CompositeTableType; [TableName.SecretBlindIndex]: Knex.CompositeTableType< TSecretBlindIndexes, TSecretBlindIndexesInsert, TSecretBlindIndexesUpdate >; - [TableName.SecretVersion]: Knex.CompositeTableType< - TSecretVersions, - TSecretVersionsInsert, - TSecretVersionsUpdate - >; - [TableName.SecretFolder]: Knex.CompositeTableType< - TSecretFolders, - TSecretFoldersInsert, - TSecretFoldersUpdate - >; + [TableName.SecretVersion]: Knex.CompositeTableType; + [TableName.SecretFolder]: Knex.CompositeTableType; [TableName.SecretFolderVersion]: Knex.CompositeTableType< TSecretFolderVersions, TSecretFolderVersionsInsert, TSecretFolderVersionsUpdate >; - [TableName.SecretTag]: Knex.CompositeTableType< - TSecretTags, - TSecretTagsInsert, - TSecretTagsUpdate - >; - [TableName.SecretImport]: Knex.CompositeTableType< - TSecretImports, - TSecretImportsInsert, - TSecretImportsUpdate - >; - [TableName.Integration]: Knex.CompositeTableType< - TIntegrations, - TIntegrationsInsert, - TIntegrationsUpdate - >; + [TableName.SecretTag]: Knex.CompositeTableType; + [TableName.SecretImport]: Knex.CompositeTableType; + [TableName.Integration]: Knex.CompositeTableType; [TableName.Webhook]: Knex.CompositeTableType; - [TableName.ServiceToken]: Knex.CompositeTableType< - TServiceTokens, - TServiceTokensInsert, - TServiceTokensUpdate - >; + [TableName.ServiceToken]: Knex.CompositeTableType; [TableName.IntegrationAuth]: Knex.CompositeTableType< TIntegrationAuths, TIntegrationAuthsInsert, TIntegrationAuthsUpdate >; - [TableName.Identity]: Knex.CompositeTableType< - TIdentities, - TIdentitiesInsert, - TIdentitiesUpdate - >; + [TableName.Identity]: Knex.CompositeTableType; [TableName.IdentityUniversalAuth]: Knex.CompositeTableType< TIdentityUniversalAuths, TIdentityUniversalAuthsInsert, @@ -362,11 +302,7 @@ declare module "knex/types/tables" { TSecretRotationOutputsInsert, TSecretRotationOutputsUpdate >; - [TableName.Snapshot]: Knex.CompositeTableType< - TSecretSnapshots, - TSecretSnapshotsInsert, - TSecretSnapshotsUpdate - >; + [TableName.Snapshot]: Knex.CompositeTableType; [TableName.SnapshotSecret]: Knex.CompositeTableType< TSecretSnapshotSecrets, TSecretSnapshotSecretsInsert, @@ -377,11 +313,7 @@ declare module "knex/types/tables" { TSecretSnapshotFoldersInsert, TSecretSnapshotFoldersUpdate >; - [TableName.SamlConfig]: Knex.CompositeTableType< - TSamlConfigs, - TSamlConfigsInsert, - TSamlConfigsUpdate - >; + [TableName.SamlConfig]: Knex.CompositeTableType; [TableName.OrgBot]: Knex.CompositeTableType; [TableName.AuditLog]: Knex.CompositeTableType; [TableName.GitAppInstallSession]: Knex.CompositeTableType< @@ -395,11 +327,7 @@ declare module "knex/types/tables" { TSecretScanningGitRisksInsert, TSecretScanningGitRisksUpdate >; - [TableName.TrustedIps]: Knex.CompositeTableType< - TTrustedIps, - TTrustedIpsInsert, - TTrustedIpsUpdate - >; + [TableName.TrustedIps]: Knex.CompositeTableType; // Junction tables [TableName.JnSecretTag]: Knex.CompositeTableType< TSecretTagJunction, diff --git a/backend/src/db/migrations/20231220052508_secret-version.ts b/backend/src/db/migrations/20231220052508_secret-version.ts index 0bcee295b..46e3264bf 100644 --- a/backend/src/db/migrations/20231220052508_secret-version.ts +++ b/backend/src/db/migrations/20231220052508_secret-version.ts @@ -38,12 +38,7 @@ export async function up(knex: Knex): Promise { } await createOnUpdateTrigger(knex, TableName.SecretVersion); // many to many relation between tags - await createJunctionTable( - knex, - TableName.SecretVersionTag, - TableName.SecretVersion, - TableName.SecretTag - ); + await createJunctionTable(knex, TableName.SecretVersionTag, TableName.SecretVersion, TableName.SecretTag); } export async function down(knex: Knex): Promise { diff --git a/backend/src/db/migrations/20231222172455_integration.ts b/backend/src/db/migrations/20231222172455_integration.ts index 4ef34cab1..43fd9986a 100644 --- a/backend/src/db/migrations/20231222172455_integration.ts +++ b/backend/src/db/migrations/20231222172455_integration.ts @@ -50,10 +50,7 @@ export async function up(knex: Knex): Promise { t.string("integration").notNullable(); t.jsonb("metadata"); t.uuid("integrationAuthId").notNullable(); - t.foreign("integrationAuthId") - .references("id") - .inTable(TableName.IntegrationAuth) - .onDelete("CASCADE"); + t.foreign("integrationAuthId").references("id").inTable(TableName.IntegrationAuth).onDelete("CASCADE"); t.uuid("envId").notNullable(); t.string("secretPath").defaultTo("/").notNullable(); t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); diff --git a/backend/src/db/migrations/20231228074908_identity-universal-auth.ts b/backend/src/db/migrations/20231228074908_identity-universal-auth.ts index 76d05db91..48d58ccd4 100644 --- a/backend/src/db/migrations/20231228074908_identity-universal-auth.ts +++ b/backend/src/db/migrations/20231228074908_identity-universal-auth.ts @@ -31,10 +31,7 @@ export async function up(knex: Knex): Promise { t.boolean("isClientSecretRevoked").defaultTo(false).notNullable(); t.timestamps(true, true, true); t.uuid("identityUAId").notNullable(); - t.foreign("identityUAId") - .references("id") - .inTable(TableName.IdentityUniversalAuth) - .onDelete("CASCADE"); + t.foreign("identityUAId").references("id").inTable(TableName.IdentityUniversalAuth).onDelete("CASCADE"); }); } await createOnUpdateTrigger(knex, TableName.IdentityUniversalAuth); diff --git a/backend/src/db/migrations/20240101054849_secret-approval-policy.ts b/backend/src/db/migrations/20240101054849_secret-approval-policy.ts index 7fde0d314..3de1ce280 100644 --- a/backend/src/db/migrations/20240101054849_secret-approval-policy.ts +++ b/backend/src/db/migrations/20240101054849_secret-approval-policy.ts @@ -21,15 +21,9 @@ export async function up(knex: Knex): Promise { await knex.schema.createTable(TableName.SecretApprovalPolicyApprover, (t) => { t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); t.uuid("approverId").notNullable(); - t.foreign("approverId") - .references("id") - .inTable(TableName.ProjectMembership) - .onDelete("CASCADE"); + t.foreign("approverId").references("id").inTable(TableName.ProjectMembership).onDelete("CASCADE"); t.uuid("policyId").notNullable(); - t.foreign("policyId") - .references("id") - .inTable(TableName.SecretApprovalPolicy) - .onDelete("CASCADE"); + t.foreign("policyId").references("id").inTable(TableName.SecretApprovalPolicy).onDelete("CASCADE"); t.timestamps(true, true, true); }); } diff --git a/backend/src/db/migrations/20240101104907_secret-approval-request.ts b/backend/src/db/migrations/20240101104907_secret-approval-request.ts index 21a9e944e..f35f87819 100644 --- a/backend/src/db/migrations/20240101104907_secret-approval-request.ts +++ b/backend/src/db/migrations/20240101104907_secret-approval-request.ts @@ -11,23 +11,14 @@ export async function up(knex: Knex): Promise { t.boolean("hasMerged").defaultTo(false).notNullable(); t.string("status").defaultTo("open").notNullable(); t.jsonb("conflicts"); - t.foreign("policyId") - .references("id") - .inTable(TableName.SecretApprovalPolicy) - .onDelete("CASCADE"); + t.foreign("policyId").references("id").inTable(TableName.SecretApprovalPolicy).onDelete("CASCADE"); t.string("slug").notNullable(); t.uuid("folderId").notNullable(); t.foreign("folderId").references("id").inTable(TableName.SecretFolder).onDelete("CASCADE"); t.uuid("statusChangeBy"); - t.foreign("statusChangeBy") - .references("id") - .inTable(TableName.ProjectMembership) - .onDelete("SET NULL"); + t.foreign("statusChangeBy").references("id").inTable(TableName.ProjectMembership).onDelete("SET NULL"); t.uuid("committerId").notNullable(); - t.foreign("committerId") - .references("id") - .inTable(TableName.ProjectMembership) - .onDelete("CASCADE"); + t.foreign("committerId").references("id").inTable(TableName.ProjectMembership).onDelete("CASCADE"); t.timestamps(true, true, true); }); } @@ -40,10 +31,7 @@ export async function up(knex: Knex): Promise { t.foreign("member").references("id").inTable(TableName.ProjectMembership).onDelete("CASCADE"); t.string("status").notNullable(); t.uuid("requestId").notNullable(); - t.foreign("requestId") - .references("id") - .inTable(TableName.SecretApprovalRequest) - .onDelete("CASCADE"); + t.foreign("requestId").references("id").inTable(TableName.SecretApprovalRequest).onDelete("CASCADE"); t.timestamps(true, true, true); }); } @@ -73,18 +61,12 @@ export async function up(knex: Knex): Promise { t.timestamps(true, true, true); // commit details t.uuid("requestId").notNullable(); - t.foreign("requestId") - .references("id") - .inTable(TableName.SecretApprovalRequest) - .onDelete("CASCADE"); + t.foreign("requestId").references("id").inTable(TableName.SecretApprovalRequest).onDelete("CASCADE"); t.string("op").notNullable(); t.uuid("secretId"); t.foreign("secretId").references("id").inTable(TableName.Secret).onDelete("SET NULL"); t.uuid("secretVersion"); - t.foreign("secretVersion") - .references("id") - .inTable(TableName.SecretVersion) - .onDelete("SET NULL"); + t.foreign("secretVersion").references("id").inTable(TableName.SecretVersion).onDelete("SET NULL"); }); } await createOnUpdateTrigger(knex, TableName.SecretApprovalRequestSecret); @@ -93,10 +75,7 @@ export async function up(knex: Knex): Promise { await knex.schema.createTable(TableName.SecretApprovalRequestSecretTag, (t) => { t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); t.uuid("secretId").notNullable(); - t.foreign("secretId") - .references("id") - .inTable(TableName.SecretApprovalRequestSecret) - .onDelete("CASCADE"); + t.foreign("secretId").references("id").inTable(TableName.SecretApprovalRequestSecret).onDelete("CASCADE"); t.uuid("tagId").notNullable(); t.foreign("tagId").references("id").inTable(TableName.SecretTag).onDelete("CASCADE"); t.timestamps(true, true, true); diff --git a/backend/src/db/migrations/20240102152111_secret-rotation.ts b/backend/src/db/migrations/20240102152111_secret-rotation.ts index f7009488a..ea962cc6e 100644 --- a/backend/src/db/migrations/20240102152111_secret-rotation.ts +++ b/backend/src/db/migrations/20240102152111_secret-rotation.ts @@ -32,10 +32,7 @@ export async function up(knex: Knex): Promise { t.uuid("secretId").notNullable(); t.foreign("secretId").references("id").inTable(TableName.Secret).onDelete("CASCADE"); t.uuid("rotationId").notNullable(); - t.foreign("rotationId") - .references("id") - .inTable(TableName.SecretRotation) - .onDelete("CASCADE"); + t.foreign("rotationId").references("id").inTable(TableName.SecretRotation).onDelete("CASCADE"); }); } } diff --git a/backend/src/db/migrations/20240104140641_secret-snapshot.ts b/backend/src/db/migrations/20240104140641_secret-snapshot.ts index 01b1e24fb..3dfb06772 100644 --- a/backend/src/db/migrations/20240104140641_secret-snapshot.ts +++ b/backend/src/db/migrations/20240104140641_secret-snapshot.ts @@ -25,10 +25,7 @@ export async function up(knex: Knex): Promise { t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); // not a relation kept like that to keep it when rolled back t.uuid("secretVersionId").notNullable(); - t.foreign("secretVersionId") - .references("id") - .inTable(TableName.SecretVersion) - .onDelete("CASCADE"); + t.foreign("secretVersionId").references("id").inTable(TableName.SecretVersion).onDelete("CASCADE"); t.uuid("snapshotId").notNullable(); t.foreign("snapshotId").references("id").inTable(TableName.Snapshot).onDelete("CASCADE"); t.timestamps(true, true, true); @@ -42,10 +39,7 @@ export async function up(knex: Knex): Promise { t.foreign("envId").references("id").inTable(TableName.Environment).onDelete("CASCADE"); // not a relation kept like that to keep it when rolled back t.uuid("folderVersionId").notNullable(); - t.foreign("folderVersionId") - .references("id") - .inTable(TableName.SecretFolderVersion) - .onDelete("CASCADE"); + t.foreign("folderVersionId").references("id").inTable(TableName.SecretFolderVersion).onDelete("CASCADE"); t.uuid("snapshotId").notNullable(); t.foreign("snapshotId").references("id").inTable(TableName.Snapshot).onDelete("CASCADE"); t.timestamps(true, true, true); diff --git a/backend/src/db/schemas/identity-org-memberships.ts b/backend/src/db/schemas/identity-org-memberships.ts index 90cf230d0..647ec7124 100644 --- a/backend/src/db/schemas/identity-org-memberships.ts +++ b/backend/src/db/schemas/identity-org-memberships.ts @@ -19,6 +19,4 @@ export const IdentityOrgMembershipsSchema = z.object({ export type TIdentityOrgMemberships = z.infer; export type TIdentityOrgMembershipsInsert = Omit; -export type TIdentityOrgMembershipsUpdate = Partial< - Omit ->; +export type TIdentityOrgMembershipsUpdate = Partial>; diff --git a/backend/src/db/schemas/identity-project-memberships.ts b/backend/src/db/schemas/identity-project-memberships.ts index 9c6bbf436..866324c8b 100644 --- a/backend/src/db/schemas/identity-project-memberships.ts +++ b/backend/src/db/schemas/identity-project-memberships.ts @@ -19,6 +19,4 @@ export const IdentityProjectMembershipsSchema = z.object({ export type TIdentityProjectMemberships = z.infer; export type TIdentityProjectMembershipsInsert = Omit; -export type TIdentityProjectMembershipsUpdate = Partial< - Omit ->; +export type TIdentityProjectMembershipsUpdate = Partial>; diff --git a/backend/src/db/schemas/identity-ua-client-secrets.ts b/backend/src/db/schemas/identity-ua-client-secrets.ts index 788a3b9ad..60f8d862f 100644 --- a/backend/src/db/schemas/identity-ua-client-secrets.ts +++ b/backend/src/db/schemas/identity-ua-client-secrets.ts @@ -24,6 +24,4 @@ export const IdentityUaClientSecretsSchema = z.object({ export type TIdentityUaClientSecrets = z.infer; export type TIdentityUaClientSecretsInsert = Omit; -export type TIdentityUaClientSecretsUpdate = Partial< - Omit ->; +export type TIdentityUaClientSecretsUpdate = Partial>; diff --git a/backend/src/db/schemas/identity-universal-auths.ts b/backend/src/db/schemas/identity-universal-auths.ts index c05ceedae..5a8f0c7ec 100644 --- a/backend/src/db/schemas/identity-universal-auths.ts +++ b/backend/src/db/schemas/identity-universal-auths.ts @@ -22,6 +22,4 @@ export const IdentityUniversalAuthsSchema = z.object({ export type TIdentityUniversalAuths = z.infer; export type TIdentityUniversalAuthsInsert = Omit; -export type TIdentityUniversalAuthsUpdate = Partial< - Omit ->; +export type TIdentityUniversalAuthsUpdate = Partial>; diff --git a/backend/src/db/schemas/secret-approval-policies-approvers.ts b/backend/src/db/schemas/secret-approval-policies-approvers.ts index 4236f79da..503299d30 100644 --- a/backend/src/db/schemas/secret-approval-policies-approvers.ts +++ b/backend/src/db/schemas/secret-approval-policies-approvers.ts @@ -15,13 +15,6 @@ export const SecretApprovalPoliciesApproversSchema = z.object({ updatedAt: z.date() }); -export type TSecretApprovalPoliciesApprovers = z.infer< - typeof SecretApprovalPoliciesApproversSchema ->; -export type TSecretApprovalPoliciesApproversInsert = Omit< - TSecretApprovalPoliciesApprovers, - TImmutableDBKeys ->; -export type TSecretApprovalPoliciesApproversUpdate = Partial< - Omit ->; +export type TSecretApprovalPoliciesApprovers = z.infer; +export type TSecretApprovalPoliciesApproversInsert = Omit; +export type TSecretApprovalPoliciesApproversUpdate = Partial>; diff --git a/backend/src/db/schemas/secret-approval-policies.ts b/backend/src/db/schemas/secret-approval-policies.ts index 7ad466447..6c331f1b1 100644 --- a/backend/src/db/schemas/secret-approval-policies.ts +++ b/backend/src/db/schemas/secret-approval-policies.ts @@ -19,6 +19,4 @@ export const SecretApprovalPoliciesSchema = z.object({ export type TSecretApprovalPolicies = z.infer; export type TSecretApprovalPoliciesInsert = Omit; -export type TSecretApprovalPoliciesUpdate = Partial< - Omit ->; +export type TSecretApprovalPoliciesUpdate = Partial>; diff --git a/backend/src/db/schemas/secret-approval-request-secret-tags.ts b/backend/src/db/schemas/secret-approval-request-secret-tags.ts index 3929c146c..f5e7ba632 100644 --- a/backend/src/db/schemas/secret-approval-request-secret-tags.ts +++ b/backend/src/db/schemas/secret-approval-request-secret-tags.ts @@ -15,13 +15,6 @@ export const SecretApprovalRequestSecretTagsSchema = z.object({ updatedAt: z.date() }); -export type TSecretApprovalRequestSecretTags = z.infer< - typeof SecretApprovalRequestSecretTagsSchema ->; -export type TSecretApprovalRequestSecretTagsInsert = Omit< - TSecretApprovalRequestSecretTags, - TImmutableDBKeys ->; -export type TSecretApprovalRequestSecretTagsUpdate = Partial< - Omit ->; +export type TSecretApprovalRequestSecretTags = z.infer; +export type TSecretApprovalRequestSecretTagsInsert = Omit; +export type TSecretApprovalRequestSecretTagsUpdate = Partial>; diff --git a/backend/src/db/schemas/secret-approval-requests-reviewers.ts b/backend/src/db/schemas/secret-approval-requests-reviewers.ts index 3b14c0eb5..a3657f1f9 100644 --- a/backend/src/db/schemas/secret-approval-requests-reviewers.ts +++ b/backend/src/db/schemas/secret-approval-requests-reviewers.ts @@ -16,13 +16,6 @@ export const SecretApprovalRequestsReviewersSchema = z.object({ updatedAt: z.date() }); -export type TSecretApprovalRequestsReviewers = z.infer< - typeof SecretApprovalRequestsReviewersSchema ->; -export type TSecretApprovalRequestsReviewersInsert = Omit< - TSecretApprovalRequestsReviewers, - TImmutableDBKeys ->; -export type TSecretApprovalRequestsReviewersUpdate = Partial< - Omit ->; +export type TSecretApprovalRequestsReviewers = z.infer; +export type TSecretApprovalRequestsReviewersInsert = Omit; +export type TSecretApprovalRequestsReviewersUpdate = Partial>; diff --git a/backend/src/db/schemas/secret-approval-requests-secrets.ts b/backend/src/db/schemas/secret-approval-requests-secrets.ts index 9dbd29db2..810a4f2cf 100644 --- a/backend/src/db/schemas/secret-approval-requests-secrets.ts +++ b/backend/src/db/schemas/secret-approval-requests-secrets.ts @@ -35,10 +35,5 @@ export const SecretApprovalRequestsSecretsSchema = z.object({ }); export type TSecretApprovalRequestsSecrets = z.infer; -export type TSecretApprovalRequestsSecretsInsert = Omit< - TSecretApprovalRequestsSecrets, - TImmutableDBKeys ->; -export type TSecretApprovalRequestsSecretsUpdate = Partial< - Omit ->; +export type TSecretApprovalRequestsSecretsInsert = Omit; +export type TSecretApprovalRequestsSecretsUpdate = Partial>; diff --git a/backend/src/db/schemas/secret-approval-requests.ts b/backend/src/db/schemas/secret-approval-requests.ts index 8e3481cb0..590c283f5 100644 --- a/backend/src/db/schemas/secret-approval-requests.ts +++ b/backend/src/db/schemas/secret-approval-requests.ts @@ -23,6 +23,4 @@ export const SecretApprovalRequestsSchema = z.object({ export type TSecretApprovalRequests = z.infer; export type TSecretApprovalRequestsInsert = Omit; -export type TSecretApprovalRequestsUpdate = Partial< - Omit ->; +export type TSecretApprovalRequestsUpdate = Partial>; diff --git a/backend/src/db/schemas/secret-scanning-git-risks.ts b/backend/src/db/schemas/secret-scanning-git-risks.ts index b6a6fb142..85cfcd376 100644 --- a/backend/src/db/schemas/secret-scanning-git-risks.ts +++ b/backend/src/db/schemas/secret-scanning-git-risks.ts @@ -43,6 +43,4 @@ export const SecretScanningGitRisksSchema = z.object({ export type TSecretScanningGitRisks = z.infer; export type TSecretScanningGitRisksInsert = Omit; -export type TSecretScanningGitRisksUpdate = Partial< - Omit ->; +export type TSecretScanningGitRisksUpdate = Partial>; diff --git a/backend/src/db/schemas/secret-version-tag-junction.ts b/backend/src/db/schemas/secret-version-tag-junction.ts index 95d4db0bb..2c9a24fee 100644 --- a/backend/src/db/schemas/secret-version-tag-junction.ts +++ b/backend/src/db/schemas/secret-version-tag-junction.ts @@ -15,6 +15,4 @@ export const SecretVersionTagJunctionSchema = z.object({ export type TSecretVersionTagJunction = z.infer; export type TSecretVersionTagJunctionInsert = Omit; -export type TSecretVersionTagJunctionUpdate = Partial< - Omit ->; +export type TSecretVersionTagJunctionUpdate = Partial>; diff --git a/backend/src/db/seed-data.ts b/backend/src/db/seed-data.ts index a9dedbb11..bb57d5bb4 100644 --- a/backend/src/db/seed-data.ts +++ b/backend/src/db/seed-data.ts @@ -48,14 +48,12 @@ export const generateUserSrpKeys = async (password: string) => { await new Promise((resolve) => { client.init({ username: seedData1.email, password: seedData1.password }, () => resolve(null)); }); - const { salt, verifier } = await new Promise<{ salt: string; verifier: string }>( - (resolve, reject) => { - client.createVerifier((err, res) => { - if (err) return reject(err); - return resolve(res); - }); - } - ); + const { salt, verifier } = await new Promise<{ salt: string; verifier: string }>((resolve, reject) => { + client.createVerifier((err, res) => { + if (err) return reject(err); + return resolve(res); + }); + }); const derivedKey = await argon2.hash(password, { salt: Buffer.from(salt), memoryCost: 65536, diff --git a/backend/src/db/seeds/3-project.ts b/backend/src/db/seeds/3-project.ts index 26f4dfced..7818d5831 100644 --- a/backend/src/db/seeds/3-project.ts +++ b/backend/src/db/seeds/3-project.ts @@ -45,7 +45,5 @@ export async function seed(knex: Knex): Promise { })) ) .returning("*"); - await knex(TableName.SecretFolder).insert( - envs.map(({ id }) => ({ name: "root", envId: id, parentId: null })) - ); + await knex(TableName.SecretFolder).insert(envs.map(({ id }) => ({ name: "root", envId: id, parentId: null }))); } diff --git a/backend/src/db/utils.ts b/backend/src/db/utils.ts index 51a097a4b..68c400596 100644 --- a/backend/src/db/utils.ts +++ b/backend/src/db/utils.ts @@ -2,12 +2,7 @@ import { Knex } from "knex"; import { TableName } from "./schemas"; -export const createJunctionTable = ( - knex: Knex, - tableName: TableName, - table1Name: TableName, - table2Name: TableName -) => +export const createJunctionTable = (knex: Knex, tableName: TableName, table1Name: TableName, table2Name: TableName) => knex.schema.createTable(tableName, (table) => { table.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); table.uuid(`${table1Name}Id`).unsigned().notNullable(); // Foreign key for table1 diff --git a/backend/src/ee/routes/v1/org-role-router.ts b/backend/src/ee/routes/v1/org-role-router.ts index 5b80f298d..4890c97a5 100644 --- a/backend/src/ee/routes/v1/org-role-router.ts +++ b/backend/src/ee/routes/v1/org-role-router.ts @@ -26,11 +26,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const role = await server.services.orgRole.createRole( - req.permission.id, - req.params.organizationId, - req.body - ); + const role = await server.services.orgRole.createRole(req.permission.id, req.params.organizationId, req.body); return { role }; } }); @@ -111,10 +107,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const roles = await server.services.orgRole.listRoles( - req.permission.id, - req.params.organizationId - ); + const roles = await server.services.orgRole.listRoles(req.permission.id, req.params.organizationId); return { data: { roles } }; } }); diff --git a/backend/src/ee/routes/v1/saml-router.ts b/backend/src/ee/routes/v1/saml-router.ts index 7f08abd35..6ddebb388 100644 --- a/backend/src/ee/routes/v1/saml-router.ts +++ b/backend/src/ee/routes/v1/saml-router.ts @@ -82,9 +82,9 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => { const serverCfg = getServerCfg(); if (!profile) throw new BadRequestError({ message: "Missing profile" }); const { firstName } = profile; - const email = profile?.email ?? profile?.emailAddress as string // emailRippling is added because in Rippling the field `email` reserved - - if (!email || !firstName){ + const email = profile?.email ?? (profile?.emailAddress as string); // emailRippling is added because in Rippling the field `email` reserved + + if (!email || !firstName) { throw new BadRequestError({ message: "Invalid request. Missing email or first name" }); } @@ -150,15 +150,11 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => { handler: (req, res) => { if (req.passportUser.isUserCompleted) { return res.redirect( - `${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent( - req.passportUser.providerAuthToken - )}` + `${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}` ); } return res.redirect( - `${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent( - req.passportUser.providerAuthToken - )}` + `${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}` ); } }); diff --git a/backend/src/ee/routes/v1/secret-approval-policy-router.ts b/backend/src/ee/routes/v1/secret-approval-policy-router.ts index eb3da2bb2..dda8dbe38 100644 --- a/backend/src/ee/routes/v1/secret-approval-policy-router.ts +++ b/backend/src/ee/routes/v1/secret-approval-policy-router.ts @@ -117,12 +117,11 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const approvals = - await server.services.secretApprovalPolicy.getSecretApprovalPolicyByProjectId({ - actor: req.permission.type, - actorId: req.permission.id, - projectId: req.query.workspaceId - }); + const approvals = await server.services.secretApprovalPolicy.getSecretApprovalPolicyByProjectId({ + actor: req.permission.type, + actorId: req.permission.id, + projectId: req.query.workspaceId + }); return { approvals }; } }); diff --git a/backend/src/ee/routes/v1/secret-approval-request-router.ts b/backend/src/ee/routes/v1/secret-approval-request-router.ts index 056da4839..f33e8b0d0 100644 --- a/backend/src/ee/routes/v1/secret-approval-request-router.ts +++ b/backend/src/ee/routes/v1/secret-approval-request-router.ts @@ -9,10 +9,7 @@ import { SecretVersionsSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; -import { - ApprovalStatus, - RequestState -} from "@app/ee/services/secret-approval-request/secret-approval-request-types"; +import { ApprovalStatus, RequestState } from "@app/ee/services/secret-approval-request/secret-approval-request-types"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -41,9 +38,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv approvers: z.string().array(), secretPath: z.string().optional().nullable() }), - commits: z - .object({ op: z.string(), secretId: z.string().nullable().optional() }) - .array(), + commits: z.object({ op: z.string(), secretId: z.string().nullable().optional() }).array(), environment: z.string(), reviewers: z.object({ member: z.string(), status: z.string() }).array(), approvers: z.string().array() @@ -176,8 +171,7 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv type: isClosing ? EventType.SECRET_APPROVAL_CLOSED : EventType.SECRET_APPROVAL_REOPENED, // eslint-disable-next-line metadata: { - [isClosing ? ("closedBy" as const) : ("reopenedBy" as const)]: - approval.statusChangeBy as string, + [isClosing ? ("closedBy" as const) : ("reopenedBy" as const)]: approval.statusChangeBy as string, secretApprovalRequestId: approval.id, secretApprovalRequestSlug: approval.slug // eslint-disable-next-line diff --git a/backend/src/ee/routes/v1/secret-scanning-router.ts b/backend/src/ee/routes/v1/secret-scanning-router.ts index 48898eddb..2970a4308 100644 --- a/backend/src/ee/routes/v1/secret-scanning-router.ts +++ b/backend/src/ee/routes/v1/secret-scanning-router.ts @@ -62,12 +62,11 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) = }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const appInstallationCompleted = - await server.services.secretScanning.getOrgInstallationStatus({ - actor: req.permission.type, - actorId: req.permission.id, - orgId: req.params.organizationId - }); + const appInstallationCompleted = await server.services.secretScanning.getOrgInstallationStatus({ + actor: req.permission.type, + actorId: req.permission.id, + orgId: req.params.organizationId + }); return { appInstallationCompleted }; } }); 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 6606bf3aa..c1368880d 100644 --- a/backend/src/ee/services/audit-log/audit-log-dal.ts +++ b/backend/src/ee/services/audit-log/audit-log-dal.ts @@ -22,17 +22,7 @@ export const auditLogDALFactory = (db: TDbClient) => { const auditLogOrm = ormify(db, TableName.AuditLog); const find = async ( - { - orgId, - projectId, - userAgentType, - startDate, - endDate, - limit = 20, - offset = 0, - actor, - eventType - }: TFindQuery, + { orgId, projectId, userAgentType, startDate, endDate, limit = 20, offset = 0, actor, eventType }: TFindQuery, tx?: Knex ) => { const sqlQuery = (tx || db)(TableName.AuditLog) 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 7f5d0007f..c1d5c6925 100644 --- a/backend/src/ee/services/audit-log/audit-log-service.ts +++ b/backend/src/ee/services/audit-log/audit-log-service.ts @@ -34,10 +34,7 @@ export const auditLogServiceFactory = ({ auditLogActor }: TListProjectAuditLogDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.AuditLogs - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs); const auditLogs = await auditLogDAL.find({ startDate, endDate, @@ -48,20 +45,17 @@ export const auditLogServiceFactory = ({ actor: auditLogActor, projectId }); - return auditLogs.map( - ({ eventType: logEventType, actor: eActor, actorMetadata, eventMetadata, ...el }) => ({ - ...el, - event: { type: logEventType, metadata: eventMetadata }, - actor: { type: eActor, metadata: actorMetadata } - }) - ); + return auditLogs.map(({ eventType: logEventType, actor: eActor, actorMetadata, eventMetadata, ...el }) => ({ + ...el, + event: { type: logEventType, metadata: eventMetadata }, + actor: { type: eActor, metadata: actorMetadata } + })); }; const createAuditLog = async (data: TCreateAuditLogDTO) => { // add all cases in which project id or org id cannot be added if (data.event.type !== EventType.LOGIN_IDENTITY_UNIVERSAL_AUTH) { - if (!data.projectId && !data.orgId) - throw new BadRequestError({ message: "Must either project id or org id" }); + if (!data.projectId && !data.orgId) throw new BadRequestError({ message: "Must either project id or org id" }); } return auditLogQueue.pushToLog(data); }; diff --git a/backend/src/ee/services/license/licence-fns.ts b/backend/src/ee/services/license/licence-fns.ts index e6fa98cb8..7014eac5f 100644 --- a/backend/src/ee/services/license/licence-fns.ts +++ b/backend/src/ee/services/license/licence-fns.ts @@ -31,11 +31,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({ secretRotation: true }); -export const setupLicenceRequestWithStore = ( - baseURL: string, - refreshUrl: string, - licenseKey: string -) => { +export const setupLicenceRequestWithStore = (baseURL: string, refreshUrl: string, licenseKey: string) => { let token: string; const licenceReq = axios.create({ baseURL, diff --git a/backend/src/ee/services/license/license-service.ts b/backend/src/ee/services/license/license-service.ts index 00e654875..6a7073b4e 100644 --- a/backend/src/ee/services/license/license-service.ts +++ b/backend/src/ee/services/license/license-service.ts @@ -20,6 +20,7 @@ import { InstanceType, TAddOrgPmtMethodDTO, TAddOrgTaxIdDTO, + TCreateOrgPortalSession, TDelOrgPmtMethodDTO, TDelOrgTaxIdDTO, TFeatureSet, @@ -31,7 +32,6 @@ import { TOrgPlansTableDTO, TOrgPmtMethodsDTO, TStartOrgTrialDTO, - TCreateOrgPortalSession, TUpdateOrgBillingDetailsDTO } from "./license-types"; @@ -47,11 +47,7 @@ const LICENSE_SERVER_CLOUD_LOGIN = "/api/auth/v1/license-server-login"; const LICENSE_SERVER_ON_PREM_LOGIN = "/api/auth/v1/licence-login"; const FEATURE_CACHE_KEY = (orgId: string, projectId?: string) => `${orgId}-${projectId || ""}`; -export const licenseServiceFactory = ({ - orgDAL, - permissionService, - licenseDAL -}: TLicenseServiceFactoryDep) => { +export const licenseServiceFactory = ({ orgDAL, permissionService, licenseDAL }: TLicenseServiceFactoryDep) => { let isValidLicense = false; let instanceType = InstanceType.OnPrem; let onPremFeatures: TFeatureSet = getDefaultOnPremFeatures(); @@ -84,9 +80,7 @@ export const licenseServiceFactory = ({ if (token) { const { data: { currentPlan } - } = await licenseServerOnPremApi.request.get<{ currentPlan: TFeatureSet }>( - "/api/license/v1/plan" - ); + } = await licenseServerOnPremApi.request.get<{ currentPlan: TFeatureSet }>("/api/license/v1/plan"); onPremFeatures = currentPlan; instanceType = InstanceType.EnterpriseOnPrem; logger.info(`Instance type: ${InstanceType.EnterpriseOnPrem}`); @@ -168,12 +162,9 @@ export const licenseServiceFactory = ({ const count = await licenseDAL.countOfOrgMembers(orgId); if (org?.customerId) { - await licenseServerCloudApi.request.patch( - `/api/license-server/v1/customers/${org.customerId}/cloud-plan`, - { - quantity: count - } - ); + await licenseServerCloudApi.request.patch(`/api/license-server/v1/customers/${org.customerId}/cloud-plan`, { + quantity: count + }); } featureStore.del(orgId); } else if (instanceType === InstanceType.EnterpriseOnPrem) { @@ -184,17 +175,9 @@ export const licenseServiceFactory = ({ }; // below all are api calls - const getOrgPlansTableByBillCycle = async ({ - orgId, - actor, - actorId, - billingCycle - }: TOrgPlansTableDTO) => { + const getOrgPlansTableByBillCycle = async ({ orgId, actor, actorId, billingCycle }: TOrgPlansTableDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const { data } = await licenseServerCloudApi.request.get( `/api/license-server/v1/cloud-products?billing-cycle=${billingCycle}` ); @@ -203,24 +186,15 @@ export const licenseServiceFactory = ({ const getOrgPlan = async ({ orgId, actor, actorId, projectId }: TOrgPlanDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const plan = await getPlan(orgId, projectId); return plan; }; const startOrgTrial = async ({ orgId, actorId, actor, success_url }: TStartOrgTrialDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.Billing - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Edit, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -241,14 +215,8 @@ export const licenseServiceFactory = ({ const createOrganizationPortalSession = async ({ orgId, actorId, actor }: TCreateOrgPortalSession) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.Billing - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Edit, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -259,7 +227,7 @@ export const licenseServiceFactory = ({ const { data: { pmtMethods } - } = await licenseServerCloudApi.request.get( + } = await licenseServerCloudApi.request.get<{ pmtMethods: string[] }>( `/api/license-server/v1/customers/${organization.customerId}/billing-details/payment-methods` ); @@ -271,34 +239,30 @@ export const licenseServiceFactory = ({ } = await licenseServerCloudApi.request.post( `/api/license-server/v1/customers/${organization.customerId}/billing-details/payment-methods`, { - success_url: appCfg.SITE_URL + "/dashboard", - cancel_url: appCfg.SITE_URL + "/dashboard" - } - ); - - return { url }; - } else { - // case: organization has payment method on file - // -> redirect to billing portal - const { - data: { url } - } = await licenseServerCloudApi.request.post( - `/api/license-server/v1/customers/${organization.customerId}/billing-details/billing-portal`, - { - return_url: appCfg.SITE_URL + "/dashboard" + success_url: `${appCfg.SITE_URL}/dashboard`, + cancel_url: `${appCfg.SITE_URL}/dashboard` } ); return { url }; } - } + // case: organization has payment method on file + // -> redirect to billing portal + const { + data: { url } + } = await licenseServerCloudApi.request.post( + `/api/license-server/v1/customers/${organization.customerId}/billing-details/billing-portal`, + { + return_url: `${appCfg.SITE_URL}/dashboard` + } + ); + + return { url }; + }; const getOrgBillingInfo = async ({ orgId, actor, actorId }: TGetOrgBillInfoDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -315,10 +279,7 @@ export const licenseServiceFactory = ({ // returns org current plan feature table const getOrgPlanTable = async ({ orgId, actor, actorId }: TGetOrgBillInfoDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -334,10 +295,7 @@ export const licenseServiceFactory = ({ const getOrgBillingDetails = async ({ orgId, actor, actorId }: TGetOrgBillInfoDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -352,18 +310,9 @@ export const licenseServiceFactory = ({ return data; }; - const updateOrgBillingDetails = async ({ - actorId, - actor, - orgId, - name, - email - }: TUpdateOrgBillingDetailsDTO) => { + const updateOrgBillingDetails = async ({ actorId, actor, orgId, name, email }: TUpdateOrgBillingDetailsDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -383,10 +332,7 @@ export const licenseServiceFactory = ({ const getOrgPmtMethods = async ({ orgId, actor, actorId }: TOrgPmtMethodsDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -403,18 +349,9 @@ export const licenseServiceFactory = ({ return pmtMethods; }; - const addOrgPmtMethods = async ({ - orgId, - actor, - actorId, - success_url, - cancel_url - }: TAddOrgPmtMethodDTO) => { + const addOrgPmtMethods = async ({ orgId, actor, actorId, success_url, cancel_url }: TAddOrgPmtMethodDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -436,10 +373,7 @@ export const licenseServiceFactory = ({ const delOrgPmtMethods = async ({ actorId, actor, orgId, pmtMethodId }: TDelOrgPmtMethodDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -456,10 +390,7 @@ export const licenseServiceFactory = ({ const getOrgTaxIds = async ({ orgId, actor, actorId }: TGetOrgTaxIdDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -477,10 +408,7 @@ export const licenseServiceFactory = ({ const addOrgTaxId = async ({ actorId, actor, orgId, type, value }: TAddOrgTaxIdDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -501,10 +429,7 @@ export const licenseServiceFactory = ({ const delOrgTaxId = async ({ orgId, actor, actorId, taxId }: TDelOrgTaxIdDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -521,10 +446,7 @@ export const licenseServiceFactory = ({ const getOrgTaxInvoices = async ({ actorId, actor, orgId }: TOrgInvoiceDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -535,18 +457,13 @@ export const licenseServiceFactory = ({ const { data: { invoices } - } = await licenseServerCloudApi.request.get( - `/api/license-server/v1/customers/${organization.customerId}/invoices` - ); + } = await licenseServerCloudApi.request.get(`/api/license-server/v1/customers/${organization.customerId}/invoices`); return invoices; }; const getOrgLicenses = async ({ orgId, actor, actorId }: TOrgLicensesDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Billing - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); if (!organization) { @@ -557,9 +474,7 @@ export const licenseServiceFactory = ({ const { data: { licenses } - } = await licenseServerCloudApi.request.get( - `/api/license-server/v1/customers/${organization.customerId}/licenses` - ); + } = await licenseServerCloudApi.request.get(`/api/license-server/v1/customers/${organization.customerId}/licenses`); return licenses; }; diff --git a/backend/src/ee/services/permission/permission-dal.ts b/backend/src/ee/services/permission/permission-dal.ts index d2529f18b..cc35fb04e 100644 --- a/backend/src/ee/services/permission/permission-dal.ts +++ b/backend/src/ee/services/permission/permission-dal.ts @@ -9,11 +9,7 @@ export const permissionDALFactory = (db: TDbClient) => { const getOrgPermission = async (userId: string, orgId: string) => { try { const membership = await db(TableName.OrgMembership) - .leftJoin( - TableName.OrgRoles, - `${TableName.OrgMembership}.roleId`, - `${TableName.OrgRoles}.id` - ) + .leftJoin(TableName.OrgRoles, `${TableName.OrgMembership}.roleId`, `${TableName.OrgRoles}.id`) .where("userId", userId) .where(`${TableName.OrgMembership}.orgId`, orgId) .select("permissions") @@ -29,11 +25,7 @@ export const permissionDALFactory = (db: TDbClient) => { const getOrgIdentityPermission = async (identityId: string, orgId: string) => { try { const membership = await db(TableName.IdentityOrgMembership) - .leftJoin( - TableName.OrgRoles, - `${TableName.IdentityOrgMembership}.roleId`, - `${TableName.OrgRoles}.id` - ) + .leftJoin(TableName.OrgRoles, `${TableName.IdentityOrgMembership}.roleId`, `${TableName.OrgRoles}.id`) .where("identityId", identityId) .where(`${TableName.IdentityOrgMembership}.orgId`, orgId) .select(selectAllTableCols(TableName.IdentityOrgMembership)) @@ -48,11 +40,7 @@ export const permissionDALFactory = (db: TDbClient) => { const getProjectPermission = async (userId: string, projectId: string) => { try { const membership = await db(TableName.ProjectMembership) - .leftJoin( - TableName.ProjectRoles, - `${TableName.ProjectMembership}.roleId`, - `${TableName.ProjectRoles}.id` - ) + .leftJoin(TableName.ProjectRoles, `${TableName.ProjectMembership}.roleId`, `${TableName.ProjectRoles}.id`) .where("userId", userId) .where(`${TableName.ProjectMembership}.projectId`, projectId) .select(selectAllTableCols(TableName.ProjectMembership)) diff --git a/backend/src/ee/services/permission/permission-service.ts b/backend/src/ee/services/permission/permission-service.ts index 8549d00ee..3daf1c20a 100644 --- a/backend/src/ee/services/permission/permission-service.ts +++ b/backend/src/ee/services/permission/permission-service.ts @@ -16,12 +16,7 @@ import { TOrgRoleDALFactory } from "@app/services/org/org-role-dal"; import { TProjectRoleDALFactory } from "@app/services/project-role/project-role-dal"; import { TServiceTokenDALFactory } from "@app/services/service-token/service-token-dal"; -import { - orgAdminPermissions, - orgMemberPermissions, - orgNoAccessPermissions, - OrgPermissionSet -} from "./org-permission"; +import { orgAdminPermissions, orgMemberPermissions, orgNoAccessPermissions, OrgPermissionSet } from "./org-permission"; import { TPermissionDALFactory } from "./permission-dal"; import { buildServiceTokenProjectPermission, @@ -188,9 +183,9 @@ export const permissionServiceFactory = ({ ? { permission: MongoAbility; membership: undefined } : { permission: MongoAbility; - membership: (T extends ActorType.USER - ? TProjectMemberships - : TIdentityProjectMemberships) & { permissions?: unknown }; + membership: (T extends ActorType.USER ? TProjectMemberships : TIdentityProjectMemberships) & { + permissions?: unknown; + }; }; const getProjectPermission = async ( @@ -214,9 +209,7 @@ export const permissionServiceFactory = ({ }; const getProjectPermissionByRole = async (role: string, projectId: string) => { - const isCustomRole = !Object.values(ProjectMembershipRole).includes( - role as ProjectMembershipRole - ); + const isCustomRole = !Object.values(ProjectMembershipRole).includes(role as ProjectMembershipRole); if (isCustomRole) { const projectRole = await projectRoleDAL.findOne({ slug: role, projectId }); if (!projectRole) throw new BadRequestError({ message: "Role not found" }); 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 c9d0989e9..9da2dd122 100644 --- a/backend/src/ee/services/saml-config/saml-config-service.ts +++ b/backend/src/ee/services/saml-config/saml-config-service.ts @@ -38,10 +38,7 @@ import { type TSamlConfigServiceFactoryDep = { samlConfigDAL: TSamlConfigDALFactory; userDAL: Pick; - orgDAL: Pick< - TOrgDALFactory, - "createMembership" | "updateMembershipById" | "findMembership" | "findOrgById" - >; + orgDAL: Pick; orgBotDAL: Pick; permissionService: Pick; licenseService: Pick; @@ -68,10 +65,7 @@ export const samlConfigServiceFactory = ({ authProvider }: TCreateSamlCfgDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.Sso - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Sso); const plan = await licenseService.getPlan(orgId); if (!plan.samlSSO) @@ -128,16 +122,8 @@ export const samlConfigServiceFactory = ({ keyEncoding: orgBot.symmetricKeyKeyEncoding as SecretKeyEncoding }); - const { - ciphertext: encryptedEntryPoint, - iv: entryPointIV, - tag: entryPointTag - } = encryptSymmetric(entryPoint, key); - const { - ciphertext: encryptedIssuer, - iv: issuerIV, - tag: issuerTag - } = encryptSymmetric(issuer, key); + const { ciphertext: encryptedEntryPoint, iv: entryPointIV, tag: entryPointTag } = encryptSymmetric(entryPoint, key); + const { ciphertext: encryptedIssuer, iv: issuerIV, tag: issuerTag } = encryptSymmetric(issuer, key); const { ciphertext: encryptedCert, iv: certIV, tag: certTag } = encryptSymmetric(cert, key); const samlConfig = await samlConfigDAL.create({ @@ -168,10 +154,7 @@ export const samlConfigServiceFactory = ({ authProvider }: TUpdateSamlCfgDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Edit, - OrgPermissionSubjects.Sso - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Sso); const plan = await licenseService.getPlan(orgId); if (!plan.samlSSO) throw new BadRequestError({ @@ -181,8 +164,7 @@ export const samlConfigServiceFactory = ({ const updateQuery: TSamlConfigsUpdate = { authProvider, isActive }; const orgBot = await orgBotDAL.findOne({ orgId }); - if (!orgBot) - throw new BadRequestError({ message: "Org bot not found", name: "OrgBotNotFound" }); + if (!orgBot) throw new BadRequestError({ message: "Org bot not found", name: "OrgBotNotFound" }); const key = infisicalSymmetricDecrypt({ ciphertext: orgBot.encryptedSymmetricKey, iv: orgBot.symmetricKeyIV, @@ -201,11 +183,7 @@ export const samlConfigServiceFactory = ({ updateQuery.entryPointTag = entryPointTag; } if (issuer) { - const { - ciphertext: encryptedIssuer, - iv: issuerIV, - tag: issuerTag - } = encryptSymmetric(issuer, key); + const { ciphertext: encryptedIssuer, iv: issuerIV, tag: issuerTag } = encryptSymmetric(issuer, key); updateQuery.encryptedIssuer = encryptedIssuer; updateQuery.issuerIV = issuerIV; updateQuery.issuerTag = issuerTag; @@ -249,15 +227,8 @@ export const samlConfigServiceFactory = ({ // when dto is type id means it's internally used if (dto.type === "org") { - const { permission } = await permissionService.getOrgPermission( - dto.actor, - dto.actorId, - ssoConfig.orgId - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Sso - ); + const { permission } = await permissionService.getOrgPermission(dto.actor, dto.actorId, ssoConfig.orgId); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Sso); } const { entryPointTag, @@ -272,8 +243,7 @@ export const samlConfigServiceFactory = ({ } = ssoConfig; const orgBot = await orgBotDAL.findOne({ orgId: ssoConfig.orgId }); - if (!orgBot) - throw new BadRequestError({ message: "Org bot not found", name: "OrgBotNotFound" }); + if (!orgBot) throw new BadRequestError({ message: "Org bot not found", name: "OrgBotNotFound" }); const key = infisicalSymmetricDecrypt({ ciphertext: orgBot.encryptedSymmetricKey, iv: orgBot.symmetricKeyIV, @@ -330,8 +300,7 @@ export const samlConfigServiceFactory = ({ const appCfg = getConfig(); let user = await userDAL.findUserByEmail(email); const isSamlSignUpDisabled = !isSignupAllowed && !user; - if (isSamlSignUpDisabled) - throw new BadRequestError({ message: "User signup disabled", name: "Saml SSO login" }); + if (isSamlSignUpDisabled) throw new BadRequestError({ message: "User signup disabled", name: "Saml SSO login" }); const organization = await orgDAL.findOrgById(orgId); if (!organization) throw new BadRequestError({ message: "Org not found" }); diff --git a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-approver-dal.ts b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-approver-dal.ts index cee303436..f32439499 100644 --- a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-approver-dal.ts +++ b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-approver-dal.ts @@ -2,9 +2,7 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; import { ormify } from "@app/lib/knex"; -export type TSecretApprovalPolicyApproverDALFactory = ReturnType< - typeof secretApprovalPolicyApproverDALFactory ->; +export type TSecretApprovalPolicyApproverDALFactory = ReturnType; export const secretApprovalPolicyApproverDALFactory = (db: TDbClient) => { const sapApproverOrm = ormify(db, TableName.SecretApprovalPolicyApprover); diff --git a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-dal.ts b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-dal.ts index b2cc41884..eec3d9a1d 100644 --- a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-dal.ts +++ b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-dal.ts @@ -3,13 +3,7 @@ import { Knex } from "knex"; import { TDbClient } from "@app/db"; import { TableName, TSecretApprovalPolicies } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; -import { - buildFindFilter, - mergeOneToManyRelation, - ormify, - selectAllTableCols, - TFindFilter -} from "@app/lib/knex"; +import { buildFindFilter, mergeOneToManyRelation, ormify, selectAllTableCols, TFindFilter } from "@app/lib/knex"; export type TSecretApprovalPolicyDALFactory = ReturnType; @@ -20,11 +14,7 @@ export const secretApprovalPolicyDALFactory = (db: TDbClient) => { tx(TableName.SecretApprovalPolicy) // eslint-disable-next-line .where(buildFindFilter(filter)) - .join( - TableName.Environment, - `${TableName.SecretApprovalPolicy}.envId`, - `${TableName.Environment}.id` - ) + .join(TableName.Environment, `${TableName.SecretApprovalPolicy}.envId`, `${TableName.Environment}.id`) .join( TableName.SecretApprovalPolicyApprover, `${TableName.SecretApprovalPolicy}.id`, @@ -60,10 +50,7 @@ export const secretApprovalPolicyDALFactory = (db: TDbClient) => { } }; - const find = async ( - filter: TFindFilter, - tx?: Knex - ) => { + const find = async (filter: TFindFilter, tx?: Knex) => { try { const docs = await sapFindQuery(tx || db, filter); const formatedDoc = mergeOneToManyRelation( 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 078d688c5..b5688545c 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,10 +2,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import picomatch from "picomatch"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError } from "@app/lib/errors"; import { containsGlobPatterns } from "@app/lib/picomatch"; import { TProjectEnvDALFactory } from "@app/services/project-env/project-env-dal"; @@ -34,9 +31,7 @@ type TSecretApprovalPolicyServiceFactoryDep = { projectMembershipDAL: Pick; }; -export type TSecretApprovalPolicyServiceFactory = ReturnType< - typeof secretApprovalPolicyServiceFactory ->; +export type TSecretApprovalPolicyServiceFactory = ReturnType; export const secretApprovalPolicyServiceFactory = ({ secretApprovalPolicyDAL, @@ -105,18 +100,10 @@ export const secretApprovalPolicyServiceFactory = ({ secretPolicyId }: TUpdateSapDTO) => { const secretApprovalPolicy = await secretApprovalPolicyDAL.findById(secretPolicyId); - if (!secretApprovalPolicy) - throw new BadRequestError({ message: "Secret approval policy not found" }); + if (!secretApprovalPolicy) throw new BadRequestError({ message: "Secret approval policy not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - secretApprovalPolicy.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.SecretApproval - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, secretApprovalPolicy.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval); const updatedSap = await secretApprovalPolicyDAL.transaction(async (tx) => { const doc = await secretApprovalPolicyDAL.updateById( @@ -162,11 +149,7 @@ export const secretApprovalPolicyServiceFactory = ({ const sapPolicy = await secretApprovalPolicyDAL.findById(secretPolicyId); if (!sapPolicy) throw new BadRequestError({ message: "Secret approval policy not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - sapPolicy.projectId - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, sapPolicy.projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, ProjectPermissionSub.SecretApproval @@ -178,20 +161,13 @@ export const secretApprovalPolicyServiceFactory = ({ const getSecretApprovalPolicyByProjectId = async ({ actorId, actor, projectId }: TListSapDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.SecretApproval - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval); const sapPolicies = await secretApprovalPolicyDAL.find({ projectId }); return sapPolicies; }; - const getSecretApprovalPolicy = async ( - projectId: string, - environment: string, - secretPath: string - ) => { + const getSecretApprovalPolicy = async (projectId: string, environment: string, secretPath: string) => { const env = await projectEnvDAL.findOne({ slug: environment, projectId }); if (!env) throw new BadRequestError({ message: "Environment not found" }); @@ -199,14 +175,11 @@ export const secretApprovalPolicyServiceFactory = ({ if (!policies.length) return; // this will filter policies either without scoped to secret path or the one that matches with secret path const policiesFilteredByPath = policies.filter( - ({ secretPath: policyPath }) => - !policyPath || picomatch.isMatch(secretPath, policyPath, { strictSlashes: false }) + ({ secretPath: policyPath }) => !policyPath || picomatch.isMatch(secretPath, policyPath, { strictSlashes: false }) ); // now sort by priority. exact secret path gets first match followed by glob followed by just env scoped // if that is tie get by first createdAt - const policiesByPriority = policiesFilteredByPath.sort( - (a, b) => getPolicyScore(b) - getPolicyScore(a) - ); + const policiesByPriority = policiesFilteredByPath.sort((a, b) => getPolicyScore(b) - getPolicyScore(a)); const finalPolicy = policiesByPriority.shift(); return finalPolicy; }; diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-dal.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-dal.ts index f1a4f3bb0..05fe1b8f8 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-dal.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-dal.ts @@ -8,13 +8,7 @@ import { TSecretApprovalRequestsSecrets } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; -import { - ormify, - selectAllTableCols, - sqlNestRelationships, - stripUndefinedInWhere, - TFindFilter -} from "@app/lib/knex"; +import { ormify, selectAllTableCols, sqlNestRelationships, stripUndefinedInWhere, TFindFilter } from "@app/lib/knex"; import { RequestState } from "./secret-approval-request-types"; @@ -36,11 +30,7 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => { const findQuery = (filter: TFindFilter, tx: Knex) => tx(TableName.SecretApprovalRequest) .where(filter) - .join( - TableName.SecretFolder, - `${TableName.SecretApprovalRequest}.folderId`, - `${TableName.SecretFolder}.id` - ) + .join(TableName.SecretFolder, `${TableName.SecretApprovalRequest}.folderId`, `${TableName.SecretFolder}.id`) .join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`) .join( TableName.SecretApprovalPolicy, @@ -92,8 +82,7 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => { { key: "reviewerMemberId", label: "reviewers" as const, - mapper: ({ reviewerMemberId: member, reviewerStatus: status }) => - member ? { member, status } : undefined + mapper: ({ reviewerMemberId: member, reviewerStatus: status }) => (member ? { member, status } : undefined) }, { key: "approverId", label: "approvers" as const, mapper: ({ approverId }) => approverId } ] @@ -114,16 +103,8 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => { .with( "temp", (tx || db)(TableName.SecretApprovalRequest) - .join( - TableName.SecretFolder, - `${TableName.SecretApprovalRequest}.folderId`, - `${TableName.SecretFolder}.id` - ) - .join( - TableName.Environment, - `${TableName.SecretFolder}.envId`, - `${TableName.Environment}.id` - ) + .join(TableName.SecretFolder, `${TableName.SecretApprovalRequest}.folderId`, `${TableName.SecretFolder}.id`) + .join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`) .join( TableName.SecretApprovalPolicyApprover, `${TableName.SecretApprovalRequest}.policyId`, @@ -147,13 +128,11 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => { return { open: parseInt( - (docs.find(({ status }) => status === RequestState.Open) as { count: string })?.count || - "0", + (docs.find(({ status }) => status === RequestState.Open) as { count: string })?.count || "0", 10 ), closed: parseInt( - (docs.find(({ status }) => status === RequestState.Closed) as { count: string })?.count || - "0", + (docs.find(({ status }) => status === RequestState.Closed) as { count: string })?.count || "0", 10 ) }; @@ -163,31 +142,15 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => { }; const findByProjectId = async ( - { - status, - limit = 20, - offset = 0, - projectId, - committer, - environment, - membershipId - }: TFindQueryFilter, + { status, limit = 20, offset = 0, projectId, committer, environment, membershipId }: TFindQueryFilter, tx?: Knex ) => { try { // akhilmhdh: If ever u wanted a 1 to so many relationship connected with pagination // this is the place u wanna look at. const query = (tx || db)(TableName.SecretApprovalRequest) - .join( - TableName.SecretFolder, - `${TableName.SecretApprovalRequest}.folderId`, - `${TableName.SecretFolder}.id` - ) - .join( - TableName.Environment, - `${TableName.SecretFolder}.envId`, - `${TableName.Environment}.id` - ) + .join(TableName.SecretFolder, `${TableName.SecretApprovalRequest}.folderId`, `${TableName.SecretFolder}.id`) + .join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`) .join( TableName.SecretApprovalPolicy, `${TableName.SecretApprovalRequest}.policyId`, @@ -266,8 +229,7 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => { { key: "reviewerMemberId", label: "reviewers" as const, - mapper: ({ reviewerMemberId: member, reviewerStatus: s }) => - member ? { member, status: s } : undefined + mapper: ({ reviewerMemberId: member, reviewerStatus: s }) => (member ? { member, status: s } : undefined) }, { key: "approverId", diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-reviewer-dal.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-reviewer-dal.ts index a2a93f258..13478f38d 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-reviewer-dal.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-reviewer-dal.ts @@ -2,9 +2,7 @@ import { TDbClient } from "@app/db"; import { TableName } from "@app/db/schemas"; import { ormify } from "@app/lib/knex"; -export type TSecretApprovalRequestReviewerDALFactory = ReturnType< - typeof secretApprovalRequestReviewerDALFactory ->; +export type TSecretApprovalRequestReviewerDALFactory = ReturnType; export const secretApprovalRequestReviewerDALFactory = (db: TDbClient) => { const secretApprovalRequestReviewerOrm = ormify(db, TableName.SecretApprovalRequestReviewer); diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-secret-dal.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-secret-dal.ts index cc78b3dff..9b4742255 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-secret-dal.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-secret-dal.ts @@ -5,9 +5,7 @@ import { SecretApprovalRequestsSecretsSchema, TableName, TSecretTags } from "@ap import { DatabaseError } from "@app/lib/errors"; import { ormify, selectAllTableCols, sqlNestRelationships } from "@app/lib/knex"; -export type TSecretApprovalRequestSecretDALFactory = ReturnType< - typeof secretApprovalRequestSecretDALFactory ->; +export type TSecretApprovalRequestSecretDALFactory = ReturnType; export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => { const secretApprovalRequestSecretOrm = ormify(db, TableName.SecretApprovalRequestSecret); @@ -25,16 +23,8 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => { `${TableName.SecretApprovalRequestSecret}.id`, `${TableName.SecretApprovalRequestSecretTag}.secretId` ) - .leftJoin( - TableName.SecretTag, - `${TableName.SecretApprovalRequestSecretTag}.tagId`, - `${TableName.SecretTag}.id` - ) - .leftJoin( - TableName.Secret, - `${TableName.SecretApprovalRequestSecret}.secretId`, - `${TableName.Secret}.id` - ) + .leftJoin(TableName.SecretTag, `${TableName.SecretApprovalRequestSecretTag}.tagId`, `${TableName.SecretTag}.id`) + .leftJoin(TableName.Secret, `${TableName.SecretApprovalRequestSecret}.secretId`, `${TableName.Secret}.id`) .leftJoin( TableName.SecretVersion, `${TableName.SecretVersion}.id`, @@ -75,37 +65,24 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => { db.ref("secretValueCiphertext").withSchema(TableName.Secret).as("orgSecValueCiphertext"), db.ref("secretCommentIV").withSchema(TableName.Secret).as("orgSecCommentIV"), db.ref("secretCommentTag").withSchema(TableName.Secret).as("orgSecCommentTag"), - db - .ref("secretCommentCiphertext") - .withSchema(TableName.Secret) - .as("orgSecCommentCiphertext") + db.ref("secretCommentCiphertext").withSchema(TableName.Secret).as("orgSecCommentCiphertext") ) .select( db.ref("version").withSchema(TableName.SecretVersion).as("secVerVersion"), db.ref("secretKeyIV").withSchema(TableName.SecretVersion).as("secVerKeyIV"), db.ref("secretKeyTag").withSchema(TableName.SecretVersion).as("secVerKeyTag"), - db - .ref("secretKeyCiphertext") - .withSchema(TableName.SecretVersion) - .as("secVerKeyCiphertext"), + db.ref("secretKeyCiphertext").withSchema(TableName.SecretVersion).as("secVerKeyCiphertext"), db.ref("secretValueIV").withSchema(TableName.SecretVersion).as("secVerValueIV"), db.ref("secretValueTag").withSchema(TableName.SecretVersion).as("secVerValueTag"), - db - .ref("secretValueCiphertext") - .withSchema(TableName.SecretVersion) - .as("secVerValueCiphertext"), + db.ref("secretValueCiphertext").withSchema(TableName.SecretVersion).as("secVerValueCiphertext"), db.ref("secretCommentIV").withSchema(TableName.SecretVersion).as("secVerCommentIV"), db.ref("secretCommentTag").withSchema(TableName.SecretVersion).as("secVerCommentTag"), - db - .ref("secretCommentCiphertext") - .withSchema(TableName.SecretVersion) - .as("secVerCommentCiphertext") + db.ref("secretCommentCiphertext").withSchema(TableName.SecretVersion).as("secVerCommentCiphertext") ); const formatedDoc = sqlNestRelationships({ data: doc, key: "id", - parentMapper: (data) => - SecretApprovalRequestsSecretsSchema.omit({ secretVersion: true }).parse(data), + parentMapper: (data) => SecretApprovalRequestsSecretsSchema.omit({ secretVersion: true }).parse(data), childrenMapper: [ { key: "tagJnId", @@ -186,12 +163,7 @@ export const secretApprovalRequestSecretDALFactory = (db: TDbClient) => { { key: "secVerTagId", label: "tags" as const, - mapper: ({ - secVerTagId: id, - secVerTagName: name, - secVerTagSlug: slug, - secVerTagColor: color - }) => ({ + mapper: ({ secVerTagId: id, secVerTagName: name, secVerTagSlug: slug, secVerTagColor: color }) => ({ // eslint-disable-next-line id, // eslint-disable-next-line 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 81be86304..d1ecd51ed 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 @@ -42,10 +42,7 @@ type TSecretApprovalRequestServiceFactoryDep = { secretApprovalRequestDAL: TSecretApprovalRequestDALFactory; secretApprovalRequestSecretDAL: TSecretApprovalRequestSecretDALFactory; secretApprovalRequestReviewerDAL: TSecretApprovalRequestReviewerDALFactory; - folderDAL: Pick< - TSecretFolderDALFactory, - "findBySecretPath" | "findById" | "findSecretPathByFolderIds" - >; + folderDAL: Pick; secretTagDAL: Pick; secretBlindIndexDAL: Pick; snapshotService: Pick; @@ -61,9 +58,7 @@ type TSecretApprovalRequestServiceFactoryDep = { secretQueueService: Pick; }; -export type TSecretApprovalRequestServiceFactory = ReturnType< - typeof secretApprovalRequestServiceFactory ->; +export type TSecretApprovalRequestServiceFactory = ReturnType; export const secretApprovalRequestServiceFactory = ({ secretApprovalRequestDAL, @@ -79,14 +74,9 @@ export const secretApprovalRequestServiceFactory = ({ secretQueueService }: TSecretApprovalRequestServiceFactoryDep) => { const requestCount = async ({ projectId, actor, actorId }: TApprovalRequestCountDTO) => { - if (actor === ActorType.SERVICE) - throw new BadRequestError({ message: "Cannot use service token" }); + if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); - const { membership } = await permissionService.getProjectPermission( - actor as ActorType.USER, - actorId, - projectId - ); + const { membership } = await permissionService.getProjectPermission(actor as ActorType.USER, actorId, projectId); const count = await secretApprovalRequestDAL.findProjectRequestCount(projectId, membership.id); return count; @@ -102,8 +92,7 @@ export const secretApprovalRequestServiceFactory = ({ limit, offset }: TListApprovalsDTO) => { - if (actor === ActorType.SERVICE) - throw new BadRequestError({ message: "Cannot use service token" }); + if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); const { membership } = await permissionService.getProjectPermission(actor, actorId, projectId); const approvals = await secretApprovalRequestDAL.findByProjectId({ @@ -119,12 +108,10 @@ export const secretApprovalRequestServiceFactory = ({ }; const getSecretApprovalDetails = async ({ actor, actorId, id }: TSecretApprovalDetailsDTO) => { - if (actor === ActorType.SERVICE) - throw new BadRequestError({ message: "Cannot use service token" }); + if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); const secretApprovalRequest = await secretApprovalRequestDAL.findById(id); - if (!secretApprovalRequest) - throw new BadRequestError({ message: "Secret approval request not found" }); + if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); const { policy } = secretApprovalRequest; const { membership } = await permissionService.getProjectPermission( @@ -149,8 +136,7 @@ export const secretApprovalRequestServiceFactory = ({ const reviewApproval = async ({ approvalId, actor, status, actorId }: TReviewRequestDTO) => { const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId); - if (!secretApprovalRequest) - throw new BadRequestError({ message: "Secret approval request not found" }); + if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" }); const { policy } = secretApprovalRequest; @@ -191,8 +177,7 @@ export const secretApprovalRequestServiceFactory = ({ const updateApprovalStatus = async ({ actorId, status, approvalId, actor }: TStatusChangeDTO) => { const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId); - if (!secretApprovalRequest) - throw new BadRequestError({ message: "Secret approval request not found" }); + if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" }); const { policy } = secretApprovalRequest; @@ -209,8 +194,7 @@ export const secretApprovalRequestServiceFactory = ({ throw new UnauthorizedError({ message: "User has no access" }); } - if (secretApprovalRequest.hasMerged) - throw new BadRequestError({ message: "Approval request has been merged" }); + if (secretApprovalRequest.hasMerged) throw new BadRequestError({ message: "Approval request has been merged" }); if (secretApprovalRequest.status === RequestState.Closed && status === RequestState.Closed) throw new BadRequestError({ message: "Approval request is already closed" }); if (secretApprovalRequest.status === RequestState.Open && status === RequestState.Open) @@ -223,22 +207,13 @@ export const secretApprovalRequestServiceFactory = ({ return { ...secretApprovalRequest, ...updatedRequest }; }; - const mergeSecretApprovalRequest = async ({ - approvalId, - actor, - actorId - }: TMergeSecretApprovalRequestDTO) => { + const mergeSecretApprovalRequest = async ({ approvalId, actor, actorId }: TMergeSecretApprovalRequestDTO) => { const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId); - if (!secretApprovalRequest) - throw new BadRequestError({ message: "Secret approval request not found" }); + if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" }); const { policy, folderId, projectId } = secretApprovalRequest; - const { membership } = await permissionService.getProjectPermission( - ActorType.USER, - actorId, - projectId - ); + const { membership } = await permissionService.getProjectPermission(ActorType.USER, actorId, projectId); if ( membership.role !== ProjectMembershipRole.Admin && secretApprovalRequest.committerId !== membership.id && @@ -256,28 +231,24 @@ export const secretApprovalRequestServiceFactory = ({ (approverId) => reviewers[approverId.toString()] === ApprovalStatus.APPROVED ).length; - if (!hasMinApproval) - throw new BadRequestError({ message: "Doesn't have minimum approvals needed" }); - const secretApprovalSecrets = await secretApprovalRequestSecretDAL.findByRequestId( - secretApprovalRequest.id - ); + if (!hasMinApproval) throw new BadRequestError({ message: "Doesn't have minimum approvals needed" }); + const secretApprovalSecrets = await secretApprovalRequestSecretDAL.findByRequestId(secretApprovalRequest.id); if (!secretApprovalSecrets) throw new BadRequestError({ message: "No secrets found" }); const conflicts: Array<{ secretId: string; op: CommitType }> = []; let secretCreationCommits = secretApprovalSecrets.filter(({ op }) => op === CommitType.Create); if (secretCreationCommits.length) { - const { secsGroupedByBlindIndex: conflictGroupByBlindIndex } = - await secretService.fnSecretBlindIndexCheckV2({ - folderId, - inputSecrets: secretCreationCommits.map(({ secretBlindIndex }) => { - if (!secretBlindIndex) { - throw new BadRequestError({ - message: "Missing secret blind index" - }); - } - return { secretBlindIndex }; - }) - }); + const { secsGroupedByBlindIndex: conflictGroupByBlindIndex } = await secretService.fnSecretBlindIndexCheckV2({ + folderId, + inputSecrets: secretCreationCommits.map(({ secretBlindIndex }) => { + if (!secretBlindIndex) { + throw new BadRequestError({ + message: "Missing secret blind index" + }); + } + return { secretBlindIndex }; + }) + }); secretCreationCommits .filter(({ secretBlindIndex }) => conflictGroupByBlindIndex[secretBlindIndex || ""]) .forEach((el) => { @@ -290,23 +261,19 @@ export const secretApprovalRequestServiceFactory = ({ let secretUpdationCommits = secretApprovalSecrets.filter(({ op }) => op === CommitType.Update); if (secretUpdationCommits.length) { - const { secsGroupedByBlindIndex: conflictGroupByBlindIndex } = - await secretService.fnSecretBlindIndexCheckV2({ - folderId, - inputSecrets: secretUpdationCommits - .filter( - ({ secretBlindIndex, secret }) => - secret && secret.secretBlindIndex !== secretBlindIndex - ) - .map(({ secretBlindIndex }) => { - if (!secretBlindIndex) { - throw new BadRequestError({ - message: "Missing secret blind index" - }); - } - return { secretBlindIndex }; - }) - }); + const { secsGroupedByBlindIndex: conflictGroupByBlindIndex } = await secretService.fnSecretBlindIndexCheckV2({ + folderId, + inputSecrets: secretUpdationCommits + .filter(({ secretBlindIndex, secret }) => secret && secret.secretBlindIndex !== secretBlindIndex) + .map(({ secretBlindIndex }) => { + if (!secretBlindIndex) { + throw new BadRequestError({ + message: "Missing secret blind index" + }); + } + return { secretBlindIndex }; + }) + }); secretUpdationCommits .filter( ({ secretBlindIndex, secretId }) => @@ -318,14 +285,11 @@ export const secretApprovalRequestServiceFactory = ({ secretUpdationCommits = secretUpdationCommits.filter( ({ secretBlindIndex, secretId }) => - Boolean(secretId) && - (secretBlindIndex ? !conflictGroupByBlindIndex[secretBlindIndex] : true) + Boolean(secretId) && (secretBlindIndex ? !conflictGroupByBlindIndex[secretBlindIndex] : true) ); } - const secretDeletionCommits = secretApprovalSecrets.filter( - ({ op }) => op === CommitType.Delete - ); + const secretDeletionCommits = secretApprovalSecrets.filter(({ op }) => op === CommitType.Delete); const mergeStatus = await secretApprovalRequestDAL.transaction(async (tx) => { const newSecrets = secretCreationCommits.length @@ -442,27 +406,20 @@ export const secretApprovalRequestServiceFactory = ({ secretPath, environment }: TGenerateSecretApprovalRequestDTO) => { - if (actor === ActorType.SERVICE) - throw new BadRequestError({ message: "Cannot use service token" }); + if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); - const { permission, membership } = await permissionService.getProjectPermission( - actor, - actorId, - projectId - ); + const { permission, membership } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { environment, secretPath }) ); const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); - if (!folder) - throw new BadRequestError({ message: "Folder not found", name: "GenSecretApproval" }); + if (!folder) throw new BadRequestError({ message: "Folder not found", name: "GenSecretApproval" }); const folderId = folder.id; const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId }); - if (!blindIndexCfg) - throw new BadRequestError({ message: "Blind index not found", name: "Update secret" }); + if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" }); const commits: Omit[] = []; const commitTagIds: Record = {}; @@ -496,38 +453,28 @@ export const secretApprovalRequestServiceFactory = ({ // get all blind index // Find all those secrets // if not throw not found - const { keyName2BlindIndex, secrets: secretsToBeUpdated } = - await secretService.fnSecretBlindIndexCheck({ - inputSecrets: updatedSecrets, - folderId, - isNew: false, - blindIndexCfg - }); + const { keyName2BlindIndex, secrets: secretsToBeUpdated } = await secretService.fnSecretBlindIndexCheck({ + inputSecrets: updatedSecrets, + folderId, + isNew: false, + blindIndexCfg + }); // now find any secret that needs to update its name // same process as above - const nameUpdatedSecrets = updatedSecrets.filter(({ newSecretName }) => - Boolean(newSecretName) - ); - const { keyName2BlindIndex: newKeyName2BlindIndex } = - await secretService.fnSecretBlindIndexCheck({ - inputSecrets: nameUpdatedSecrets, - folderId, - isNew: true, - blindIndexCfg - }); + const nameUpdatedSecrets = updatedSecrets.filter(({ newSecretName }) => Boolean(newSecretName)); + const { keyName2BlindIndex: newKeyName2BlindIndex } = await secretService.fnSecretBlindIndexCheck({ + inputSecrets: nameUpdatedSecrets, + folderId, + isNew: true, + blindIndexCfg + }); - const secsGroupedByBlindIndex = groupBy( - secretsToBeUpdated, - (el) => el.secretBlindIndex as string - ); + const secsGroupedByBlindIndex = groupBy(secretsToBeUpdated, (el) => el.secretBlindIndex as string); const updatedSecretIds = updatedSecrets.map( (el) => secsGroupedByBlindIndex[keyName2BlindIndex[el.secretName]][0].id ); - const latestSecretVersions = await secretVersionDAL.findLatestVersionMany( - folderId, - updatedSecretIds - ); + const latestSecretVersions = await secretVersionDAL.findLatestVersionMany(folderId, updatedSecretIds); commits.push( ...updatedSecrets.map(({ newSecretName, secretName, tagIds, ...el }) => { const secretId = secsGroupedByBlindIndex[keyName2BlindIndex[secretName]][0].id; @@ -562,17 +509,13 @@ export const secretApprovalRequestServiceFactory = ({ blindIndexCfg }); const secretsGroupedByBlindIndex = groupBy(secrets, (i) => { - if (!i.secretBlindIndex) - throw new BadRequestError({ message: "Missing secret blind index" }); + if (!i.secretBlindIndex) throw new BadRequestError({ message: "Missing secret blind index" }); return i.secretBlindIndex; }); const deletedSecretIds = deletedSecrets.map( (el) => secretsGroupedByBlindIndex[keyName2BlindIndex[el.secretName]][0].id ); - const latestSecretVersions = await secretVersionDAL.findLatestVersionMany( - folderId, - deletedSecretIds - ); + const latestSecretVersions = await secretVersionDAL.findLatestVersionMany(folderId, deletedSecretIds); commits.push( ...deletedSecrets.map((el) => { const secretId = secretsGroupedByBlindIndex[keyName2BlindIndex[el.secretName]][0].id; diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-types.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-types.ts index c010277d5..008b977e6 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-types.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-types.ts @@ -1,8 +1,4 @@ -import { - TImmutableDBKeys, - TSecretApprovalPolicies, - TSecretApprovalRequestsSecrets -} from "@app/db/schemas"; +import { TImmutableDBKeys, TSecretApprovalPolicies, TSecretApprovalRequestsSecrets } from "@app/db/schemas"; import { TProjectPermission } from "@app/lib/types"; export enum CommitType { @@ -24,14 +20,7 @@ export enum ApprovalStatus { type TApprovalCreateSecret = Omit< TSecretApprovalRequestsSecrets, - | TImmutableDBKeys - | "version" - | "algorithm" - | "keyEncoding" - | "requestId" - | "op" - | "secretVersion" - | "secretBlindIndex" + TImmutableDBKeys | "version" | "algorithm" | "keyEncoding" | "requestId" | "op" | "secretVersion" | "secretBlindIndex" > & { secretName: string; tagIds?: string[]; diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-dal.ts b/backend/src/ee/services/secret-rotation/secret-rotation-dal.ts index d1504e3d7..7feafdc6b 100644 --- a/backend/src/ee/services/secret-rotation/secret-rotation-dal.ts +++ b/backend/src/ee/services/secret-rotation/secret-rotation-dal.ts @@ -14,21 +14,13 @@ export const secretRotationDALFactory = (db: TDbClient) => { const findQuery = (filter: TFindFilter, tx: Knex) => tx(TableName.SecretRotation) .where(filter) - .join( - TableName.Environment, - `${TableName.SecretRotation}.envId`, - `${TableName.Environment}.id` - ) + .join(TableName.Environment, `${TableName.SecretRotation}.envId`, `${TableName.Environment}.id`) .leftJoin( TableName.SecretRotationOutput, `${TableName.SecretRotation}.id`, `${TableName.SecretRotationOutput}.rotationId` ) - .join( - TableName.Secret, - `${TableName.SecretRotationOutput}.secretId`, - `${TableName.Secret}.id` - ) + .join(TableName.Secret, `${TableName.SecretRotationOutput}.secretId`, `${TableName.Secret}.id`) .select(selectAllTableCols(TableName.SecretRotation)) .select(tx.ref("name").withSchema(TableName.Environment).as("envName")) .select(tx.ref("slug").withSchema(TableName.Environment).as("envSlug")) @@ -102,11 +94,7 @@ export const secretRotationDALFactory = (db: TDbClient) => { const findById = async (id: string, tx?: Knex) => { try { const doc = await (tx || db)(TableName.SecretRotation) - .join( - TableName.Environment, - `${TableName.SecretRotation}.envId`, - `${TableName.Environment}.id` - ) + .join(TableName.Environment, `${TableName.SecretRotation}.envId`, `${TableName.Environment}.id`) .where({ [`${TableName.SecretRotation}.id` as "id"]: id }) .select(selectAllTableCols(TableName.SecretRotation)) .select( @@ -125,8 +113,7 @@ export const secretRotationDALFactory = (db: TDbClient) => { } }; - const findRotationOutputsByRotationId = async (rotationId: string) => - secretRotationOutputOrm.find({ rotationId }); + const findRotationOutputsByRotationId = async (rotationId: string) => secretRotationOutputOrm.find({ rotationId }); return { ...secretRotationOrm, diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue-fn.ts b/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue-fn.ts index 5ed14f490..c67477bfd 100644 --- a/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue-fn.ts +++ b/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue-fn.ts @@ -11,12 +11,7 @@ import knex from "knex"; import { getConfig } from "@app/lib/config/env"; import { alphaNumericNanoId } from "@app/lib/nanoid"; -import { - TAssignOp, - TDbProviderClients, - TDirectAssignOp, - THttpProviderFunction -} from "../templates/types"; +import { TAssignOp, TDbProviderClients, TDirectAssignOp, THttpProviderFunction } from "../templates/types"; import { TSecretRotationData, TSecretRotationDbFn } from "./secret-rotation-queue-types"; const REGEX = /\${([^}]+)}/g; @@ -64,10 +59,7 @@ const getInterpolationValue = (variables: TSecretRotationData) => (key: string) return variables[type as keyof TSecretRotationData][keyName]; }; -export const secretRotationHttpFn = async ( - func: THttpProviderFunction, - variables: TSecretRotationData -) => { +export const secretRotationHttpFn = async (func: THttpProviderFunction, variables: TSecretRotationData) => { // string interpolation const headers = interpolate(func.header, getInterpolationValue(variables)); const url = interpolate(func.url, getInterpolationValue(variables)); @@ -117,10 +109,7 @@ export const secretRotationDbFn = async ({ return data; }; -export const secretRotationPreSetFn = ( - op: Record, - variables: TSecretRotationData -) => { +export const secretRotationPreSetFn = (op: Record, variables: TSecretRotationData) => { const getValFn = getInterpolationValue(variables); Object.entries(op || {}).forEach(([key, assignFn]) => { const [type, keyName] = key.split(".") as [keyof TSecretRotationData, string]; @@ -128,10 +117,7 @@ export const secretRotationPreSetFn = ( }); }; -export const secretRotationHttpSetFn = async ( - func: THttpProviderFunction, - variables: TSecretRotationData -) => { +export const secretRotationHttpSetFn = async (func: THttpProviderFunction, variables: TSecretRotationData) => { const getValFn = getInterpolationValue(variables); // http setter const res = await secretRotationHttpFn(func, variables); @@ -145,10 +131,7 @@ export const secretRotationHttpSetFn = async ( }); }; -export const getDbSetQuery = ( - db: TDbProviderClients, - variables: { username: string; password: string } -) => { +export const getDbSetQuery = (db: TDbProviderClients, variables: { username: string; password: string }) => { if (db === TDbProviderClients.Pg) { return { query: `ALTER USER ?? WITH PASSWORD '${variables.password}'`, diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue.ts b/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue.ts index 978f9ea71..9e69f0a8f 100644 --- a/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue.ts +++ b/backend/src/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue.ts @@ -18,11 +18,7 @@ import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; import { TSecretRotationDALFactory } from "../secret-rotation-dal"; import { rotationTemplates } from "../templates"; -import { - TDbProviderClients, - TProviderFunctionTypes, - TSecretRotationProviderTemplate -} from "../templates/types"; +import { TDbProviderClients, TProviderFunctionTypes, TSecretRotationProviderTemplate } from "../templates/types"; import { getDbSetQuery, secretRotationDbFn, @@ -30,11 +26,7 @@ import { secretRotationHttpSetFn, secretRotationPreSetFn } from "./secret-rotation-queue-fn"; -import { - TSecretRotationData, - TSecretRotationDbFn, - TSecretRotationEncData -} from "./secret-rotation-queue-types"; +import { TSecretRotationData, TSecretRotationDbFn, TSecretRotationEncData } from "./secret-rotation-queue-types"; export type TSecretRotationQueueFactory = ReturnType; @@ -78,10 +70,7 @@ export const secretRotationQueueFactory = ({ jobId: rotationId, repeat: { // on prod it this will be in days, in development this will be second - every: - appCfg.NODE_ENV === "development" - ? secondsToMillis(interval) - : daysToMillisecond(interval), + every: appCfg.NODE_ENV === "development" ? secondsToMillis(interval) : daysToMillisecond(interval), immediately: true } } @@ -95,10 +84,7 @@ export const secretRotationQueueFactory = ({ QueueJobs.SecretRotation, { // on prod it this will be in days, in development this will be second - every: - appCfg.NODE_ENV === "development" - ? secondsToMillis(interval) - : daysToMillisecond(interval) + every: appCfg.NODE_ENV === "development" ? secondsToMillis(interval) : daysToMillisecond(interval) }, rotationId ); @@ -108,22 +94,16 @@ export const secretRotationQueueFactory = ({ const { rotationId } = job.data; logger.info(`secretRotationQueue.process: [rotationDocument=${rotationId}]`); const secretRotation = await secretRotationDAL.findById(rotationId); - const rotationProvider = rotationTemplates.find( - ({ name }) => name === secretRotation?.provider - ); + const rotationProvider = rotationTemplates.find(({ name }) => name === secretRotation?.provider); try { - if (!rotationProvider || !secretRotation) - throw new DisableRotationErrors({ message: "Provider not found" }); + if (!rotationProvider || !secretRotation) throw new DisableRotationErrors({ message: "Provider not found" }); const rotationOutputs = await secretRotationDAL.findRotationOutputsByRotationId(rotationId); - if (!rotationOutputs.length) - throw new DisableRotationErrors({ message: "Secrets not found" }); + if (!rotationOutputs.length) throw new DisableRotationErrors({ message: "Secrets not found" }); // deep copy - const provider = JSON.parse( - JSON.stringify(rotationProvider) - ) as TSecretRotationProviderTemplate; + const provider = JSON.parse(JSON.stringify(rotationProvider)) as TSecretRotationProviderTemplate; // now get the encrypted variable values // in includes the inputs, the previous outputs @@ -156,20 +136,11 @@ export const secretRotationQueueFactory = ({ ? variables.inputs.username2 : variables.inputs.username1; } else { - newCredential.internal.username = lastCred - ? lastCred.internal.username - : variables.inputs.username1; + newCredential.internal.username = lastCred ? lastCred.internal.username : variables.inputs.username1; } // set a random value for new password newCredential.internal.rotated_password = alphaNumericNanoId(32); - const { - admin_username: username, - admin_password: password, - host, - database, - port, - ca - } = newCredential.inputs; + const { admin_username: username, admin_password: password, host, database, port, ca } = newCredential.inputs; const dbFunctionArg = { username, password, @@ -177,10 +148,7 @@ export const secretRotationQueueFactory = ({ database, port, ca: ca as string, - client: - provider.template.client === TDbProviderClients.MySql - ? "mysql2" - : provider.template.client + client: provider.template.client === TDbProviderClients.MySql ? "mysql2" : provider.template.client } as TSecretRotationDbFn; // set function await secretRotationDbFn({ 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 88f555d94..e10d7fa63 100644 --- a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts +++ b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts @@ -47,10 +47,7 @@ export const secretRotationServiceFactory = ({ }: TSecretRotationServiceFactoryDep) => { const getProviderTemplates = async ({ actor, actorId, projectId }: TProjectPermission) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.SecretRotation - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation); return { custom: [], @@ -93,8 +90,7 @@ export const secretRotationServiceFactory = ({ const plan = await licenseService.getPlan(project.orgId); if (!plan.secretRotation) throw new BadRequestError({ - message: - "Failed to add secret rotation due to plan restriction. Upgrade plan to add secret rotation." + message: "Failed to add secret rotation due to plan restriction. Upgrade plan to add secret rotation." }); const selectedTemplate = rotationTemplates.find(({ name }) => name === provider); @@ -152,24 +148,14 @@ export const secretRotationServiceFactory = ({ const [doc] = await secretRotationDAL.find({ id: rotationId }); if (!doc) throw new BadRequestError({ message: "Rotation not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - doc.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.SecretRotation - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, doc.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation); return doc; }; const getByProjectId = async ({ actorId, projectId, actor }: TListByProjectIdDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.SecretRotation - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation); const doc = await secretRotationDAL.find({ projectId }); return doc; }; @@ -182,19 +168,11 @@ export const secretRotationServiceFactory = ({ const plan = await licenseService.getPlan(project.orgId); if (!plan.secretRotation) throw new BadRequestError({ - message: - "Failed to add secret rotation due to plan restriction. Upgrade plan to add secret rotation." + message: "Failed to add secret rotation due to plan restriction. Upgrade plan to add secret rotation." }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - doc.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.SecretRotation - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, doc.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretRotation); await secretRotationQueue.removeFromQueue(doc.id, doc.interval); await secretRotationQueue.addToQueue(doc.id, doc.interval); return doc; @@ -204,11 +182,7 @@ export const secretRotationServiceFactory = ({ const doc = await secretRotationDAL.findById(rotationId); if (!doc) throw new BadRequestError({ message: "Rotation not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - doc.projectId - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, doc.projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, ProjectPermissionSub.SecretRotation diff --git a/backend/src/ee/services/secret-rotation/templates/mysql.ts b/backend/src/ee/services/secret-rotation/templates/mysql.ts index 86a382d6e..723560a3e 100644 --- a/backend/src/ee/services/secret-rotation/templates/mysql.ts +++ b/backend/src/ee/services/secret-rotation/templates/mysql.ts @@ -23,15 +23,7 @@ export const MYSQL_TEMPLATE = { }, ca: { type: "string", desc: "SSL certificate for db auth(string)" } }, - required: [ - "admin_username", - "admin_password", - "host", - "database", - "username1", - "username2", - "port" - ], + required: ["admin_username", "admin_password", "host", "database", "username1", "username2", "port"], additionalProperties: false }, outputs: { diff --git a/backend/src/ee/services/secret-rotation/templates/postgres.ts b/backend/src/ee/services/secret-rotation/templates/postgres.ts index 318ca650d..c894631cb 100644 --- a/backend/src/ee/services/secret-rotation/templates/postgres.ts +++ b/backend/src/ee/services/secret-rotation/templates/postgres.ts @@ -23,15 +23,7 @@ export const POSTGRES_TEMPLATE = { }, ca: { type: "string", desc: "SSL certificate for db auth(string)" } }, - required: [ - "admin_username", - "admin_password", - "host", - "database", - "username1", - "username2", - "port" - ], + required: ["admin_username", "admin_password", "host", "database", "username1", "username2", "port"], additionalProperties: false }, outputs: { diff --git a/backend/src/ee/services/secret-scanning/git-app-dal.ts b/backend/src/ee/services/secret-scanning/git-app-dal.ts index 2a7014180..8044b0d6b 100644 --- a/backend/src/ee/services/secret-scanning/git-app-dal.ts +++ b/backend/src/ee/services/secret-scanning/git-app-dal.ts @@ -12,11 +12,7 @@ export const gitAppDALFactory = (db: TDbClient) => { const upsert = async (data: TGitAppOrgInsert, tx?: Knex) => { try { - const [doc] = await (tx || db)(TableName.GitAppOrg) - .insert(data) - .onConflict("orgId") - .merge() - .returning("*"); + const [doc] = await (tx || db)(TableName.GitAppOrg).insert(data).onConflict("orgId").merge().returning("*"); return doc; } catch (error) { throw new DatabaseError({ error, name: "UpsertGitAppOrm" }); diff --git a/backend/src/ee/services/secret-scanning/secret-scanning-dal.ts b/backend/src/ee/services/secret-scanning/secret-scanning-dal.ts index 98260a0dc..828322ad2 100644 --- a/backend/src/ee/services/secret-scanning/secret-scanning-dal.ts +++ b/backend/src/ee/services/secret-scanning/secret-scanning-dal.ts @@ -12,10 +12,7 @@ export const secretScanningDALFactory = (db: TDbClient) => { const upsert = async (data: TSecretScanningGitRisksInsert[], tx?: Knex) => { try { - const docs = await (tx || db)(TableName.SecretScanningGitRisk) - .insert(data) - .onConflict("fingerprint") - .merge(); + const docs = await (tx || db)(TableName.SecretScanningGitRisk).insert(data).onConflict("fingerprint").merge(); return docs; } catch (error) { throw new DatabaseError({ error, name: "GitRiskUpsert" }); diff --git a/backend/src/ee/services/secret-scanning/secret-scanning-queue/secret-scanning-queue.ts b/backend/src/ee/services/secret-scanning/secret-scanning-queue/secret-scanning-queue.ts index 218aceef4..aab8d1218 100644 --- a/backend/src/ee/services/secret-scanning/secret-scanning-queue/secret-scanning-queue.ts +++ b/backend/src/ee/services/secret-scanning/secret-scanning-queue/secret-scanning-queue.ts @@ -10,15 +10,8 @@ import { TTelemetryServiceFactory } from "@app/services/telemetry/telemetry-serv import { PostHogEventTypes } from "@app/services/telemetry/telemetry-types"; import { TSecretScanningDALFactory } from "../secret-scanning-dal"; -import { - scanContentAndGetFindings, - scanFullRepoContentAndGetFindings -} from "./secret-scanning-fns"; -import { - SecretMatch, - TScanFullRepoEventPayload, - TScanPushEventPayload -} from "./secret-scanning-queue-types"; +import { scanContentAndGetFindings, scanFullRepoContentAndGetFindings } from "./secret-scanning-fns"; +import { SecretMatch, TScanFullRepoEventPayload, TScanPushEventPayload } from "./secret-scanning-queue-types"; type TSecretScanningQueueFactoryDep = { queueService: TQueueServiceFactory; 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 5410d0eec..e150f30f3 100644 --- a/backend/src/ee/services/secret-scanning/secret-scanning-service.ts +++ b/backend/src/ee/services/secret-scanning/secret-scanning-service.ts @@ -4,10 +4,7 @@ import { ForbiddenError } from "@casl/ability"; import { WebhookEventMap } from "@octokit/webhooks-types"; import { ProbotOctokit } from "probot"; -import { - OrgPermissionActions, - OrgPermissionSubjects -} from "@app/ee/services/permission/org-permission"; +import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { getConfig } from "@app/lib/config/env"; import { UnauthorizedError } from "@app/lib/errors"; @@ -44,30 +41,19 @@ export const secretScanningServiceFactory = ({ }: TSecretScanningServiceFactoryDep) => { const createInstallationSession = async ({ actor, orgId, actorId }: TInstallAppSessionDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.SecretScanning - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning); const sessionId = crypto.randomBytes(16).toString("hex"); await gitAppInstallSessionDAL.upsert({ orgId, sessionId, userId: actorId }); return { sessionId }; }; - const linkInstallationToOrg = async ({ - sessionId, - actorId, - installationId, - actor - }: TLinkInstallSessionDTO) => { + const linkInstallationToOrg = async ({ sessionId, actorId, installationId, actor }: TLinkInstallSessionDTO) => { const session = await gitAppInstallSessionDAL.findOne({ sessionId }); if (!session) throw new UnauthorizedError({ message: "Session not found" }); const { permission } = await permissionService.getOrgPermission(actor, actorId, session.orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.SecretScanning - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning); const installatedApp = await gitAppOrgDAL.transaction(async (tx) => { await gitAppInstallSessionDAL.deleteById(session.id, tx); return gitAppOrgDAL.upsert({ orgId: session.orgId, installationId, userId: actorId }, tx); @@ -99,10 +85,7 @@ export const secretScanningServiceFactory = ({ const getOrgInstallationStatus = async ({ actorId, orgId, actor }: TGetOrgInstallStatusDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.SecretScanning - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning); const appInstallation = await gitAppOrgDAL.findOne({ orgId }); return Boolean(appInstallation); @@ -110,26 +93,14 @@ export const secretScanningServiceFactory = ({ const getRisksByOrg = async ({ actor, orgId, actorId }: TGetOrgRisksDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.SecretScanning - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning); const risks = await secretScanningDAL.find({ orgId }, { sort: [["createdAt", "desc"]] }); return { risks }; }; - const updateRiskStatus = async ({ - actorId, - orgId, - actor, - riskId, - status - }: TUpdateRiskStatusDTO) => { + const updateRiskStatus = async ({ actorId, orgId, actor, riskId, status }: TUpdateRiskStatusDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Edit, - OrgPermissionSubjects.SecretScanning - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.SecretScanning); const isRiskResolved = Boolean( [ @@ -169,9 +140,7 @@ export const secretScanningServiceFactory = ({ const handleRepoDeleteEvent = async (installationId: string, repositoryIds: string[]) => { await secretScanningDAL.transaction(async (tx) => { if (repositoryIds.length) { - await Promise.all( - repositoryIds.map((repoId) => secretScanningDAL.delete({ repositoryId: repoId }, tx)) - ); + await Promise.all(repositoryIds.map((repoId) => secretScanningDAL.delete({ repositoryId: repoId }, tx))); } await gitAppOrgDAL.delete({ installationId }, tx); }); 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 d1e5bad6b..26148958f 100644 --- a/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts +++ b/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts @@ -29,17 +29,11 @@ type TSecretSnapshotServiceFactoryDep = { snapshotSecretDAL: TSnapshotSecretDALFactory; snapshotFolderDAL: TSnapshotFolderDALFactory; secretVersionDAL: Pick; - folderVersionDAL: Pick< - TSecretFolderVersionDALFactory, - "findLatestVersionByFolderId" | "insertMany" - >; + folderVersionDAL: Pick; secretDAL: Pick; secretTagDAL: Pick; secretVersionTagDAL: Pick; - folderDAL: Pick< - TSecretFolderDALFactory, - "findById" | "findBySecretPath" | "delete" | "insertMany" - >; + folderDAL: Pick; permissionService: Pick; licenseService: Pick; }; @@ -67,10 +61,7 @@ export const secretSnapshotServiceFactory = ({ path }: TProjectSnapshotCountDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.SecretRollback - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); const folder = await folderDAL.findBySecretPath(projectId, environment, path); if (!folder) throw new BadRequestError({ message: "Folder not found" }); @@ -89,40 +80,26 @@ export const secretSnapshotServiceFactory = ({ offset = 0 }: TProjectSnapshotListDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.SecretRollback - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); const folder = await folderDAL.findBySecretPath(projectId, environment, path); if (!folder) throw new BadRequestError({ message: "Folder not found" }); - const snapshots = await snapshotDAL.find( - { folderId: folder.id }, - { limit, offset, sort: [["createdAt", "desc"]] } - ); + const snapshots = await snapshotDAL.find({ folderId: folder.id }, { limit, offset, sort: [["createdAt", "desc"]] }); return snapshots; }; const getSnapshotData = async ({ actorId, actor, id }: TGetSnapshotDataDTO) => { const snapshot = await snapshotDAL.findSecretSnapshotDataById(id); if (!snapshot) throw new BadRequestError({ message: "Snapshot not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - snapshot.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.SecretRollback - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, snapshot.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); return snapshot; }; const performSnapshot = async (folderId: string) => { try { - if (!licenseService.isValidLicense) - throw new InternalServerError({ message: "Invalid license" }); + if (!licenseService.isValidLicense) throw new InternalServerError({ message: "Invalid license" }); const snapshot = await snapshotDAL.transaction(async (tx) => { const folder = await folderDAL.findById(folderId, tx); @@ -170,11 +147,7 @@ export const secretSnapshotServiceFactory = ({ const snapshot = await snapshotDAL.findById(snapshotId); if (!snapshot) throw new BadRequestError({ message: "Snapshot not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - snapshot.projectId - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, snapshot.projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, ProjectPermissionSub.SecretRollback @@ -199,9 +172,7 @@ export const secretSnapshotServiceFactory = ({ id, // this means don't bump up the version if not root folder // because below ones can be same version as nothing changed - version: deletedTopLevelFolders[folderId] - ? latestFolderVersion + 1 - : latestFolderVersion, + version: deletedTopLevelFolders[folderId] ? latestFolderVersion + 1 : latestFolderVersion, name, parentId: folderId })) @@ -211,22 +182,10 @@ export const secretSnapshotServiceFactory = ({ const secrets = await secretDAL.insertMany( rollbackSnaps.flatMap(({ secretVersions, folderId }) => secretVersions.map( - ({ - latestSecretVersion, - version, - updatedAt, - createdAt, - secretId, - envId, - id, - tags, - ...el - }) => ({ + ({ latestSecretVersion, version, updatedAt, createdAt, secretId, envId, id, tags, ...el }) => ({ ...el, id: secretId, - version: deletedTopLevelSecsGroupById[secretId] - ? latestSecretVersion + 1 - : latestSecretVersion, + version: deletedTopLevelSecsGroupById[secretId] ? latestSecretVersion + 1 : latestSecretVersion, folderId }) ) @@ -239,8 +198,7 @@ export const secretSnapshotServiceFactory = ({ secretVersions.forEach((secVer) => { secVer.tags.forEach((tag) => { secretTagsToBeInsert.push({ secretsId: secVer.secretId, secret_tagsId: tag.id }); - if (!secretVerTagToBeInsert?.[secVer.secretId]) - secretVerTagToBeInsert[secVer.secretId] = []; + if (!secretVerTagToBeInsert?.[secVer.secretId]) secretVerTagToBeInsert[secVer.secretId] = []; secretVerTagToBeInsert[secVer.secretId].push(tag.id); }); }); diff --git a/backend/src/ee/services/secret-snapshot/snapshot-dal.ts b/backend/src/ee/services/secret-snapshot/snapshot-dal.ts index 912e9273a..41524c6eb 100644 --- a/backend/src/ee/services/secret-snapshot/snapshot-dal.ts +++ b/backend/src/ee/services/secret-snapshot/snapshot-dal.ts @@ -57,11 +57,7 @@ export const snapshotDALFactory = (db: TDbClient) => { const data = await (tx || db)(TableName.Snapshot) .where(`${TableName.Snapshot}.id`, snapshotId) .join(TableName.Environment, `${TableName.Snapshot}.envId`, `${TableName.Environment}.id`) - .leftJoin( - TableName.SnapshotSecret, - `${TableName.Snapshot}.id`, - `${TableName.SnapshotSecret}.snapshotId` - ) + .leftJoin(TableName.SnapshotSecret, `${TableName.Snapshot}.id`, `${TableName.SnapshotSecret}.snapshotId`) .leftJoin( TableName.SecretVersion, `${TableName.SnapshotSecret}.secretVersionId`, @@ -77,11 +73,7 @@ export const snapshotDALFactory = (db: TDbClient) => { `${TableName.SecretVersionTag}.${TableName.SecretTag}Id`, `${TableName.SecretTag}.id` ) - .leftJoin( - TableName.SnapshotFolder, - `${TableName.SnapshotFolder}.snapshotId`, - `${TableName.Snapshot}.id` - ) + .leftJoin(TableName.SnapshotFolder, `${TableName.SnapshotFolder}.snapshotId`, `${TableName.Snapshot}.id`) .leftJoin( TableName.SecretFolderVersion, `${TableName.SnapshotFolder}.folderVersionId`, @@ -131,13 +123,13 @@ export const snapshotDALFactory = (db: TDbClient) => { { key: "tagVersionId", label: "tags" as const, - mapper: ({ - tagId: id, - tagName: name, - tagSlug: slug, - tagColor: color, - tagVersionId: vId - }) => ({ id, name, slug, color, vId }) + mapper: ({ tagId: id, tagName: name, tagSlug: slug, tagColor: color, tagVersionId: vId }) => ({ + id, + name, + slug, + color, + vId + }) } ] }, @@ -192,11 +184,7 @@ export const snapshotDALFactory = (db: TDbClient) => { ) .from(TableName.Snapshot) .join( - db(TableName.Snapshot) - .groupBy("folderId") - .max("createdAt") - .select("folderId") - .as("latestVersion"), + db(TableName.Snapshot).groupBy("folderId").max("createdAt").select("folderId").as("latestVersion"), `${TableName.Snapshot}.createdAt`, "latestVersion.max" ) @@ -215,11 +203,7 @@ export const snapshotDALFactory = (db: TDbClient) => { }) .orderBy("depth", "asc") .from("parent") - .leftJoin( - TableName.SnapshotSecret, - `parent.id`, - `${TableName.SnapshotSecret}.snapshotId` - ) + .leftJoin(TableName.SnapshotSecret, `parent.id`, `${TableName.SnapshotSecret}.snapshotId`) .leftJoin( TableName.SecretVersion, `${TableName.SnapshotSecret}.secretVersionId`, @@ -272,11 +256,7 @@ export const snapshotDALFactory = (db: TDbClient) => { const formated = sqlNestRelationships({ data, key: "snapshotId", - parentMapper: ({ - snapshotId: id, - snapshotFolderId: folderId, - snapshotParentFolderId: parentFolderId - }) => ({ + parentMapper: ({ snapshotId: id, snapshotFolderId: folderId, snapshotParentFolderId: parentFolderId }) => ({ id, folderId, parentFolderId @@ -293,13 +273,13 @@ export const snapshotDALFactory = (db: TDbClient) => { { key: "tagVersionId", label: "tags" as const, - mapper: ({ - tagId: id, - tagName: name, - tagSlug: slug, - tagColor: color, - tagVersionId: vId - }) => ({ id, name, slug, color, vId }) + mapper: ({ tagId: id, tagName: name, tagSlug: slug, tagColor: color, tagVersionId: vId }) => ({ + id, + name, + slug, + color, + vId + }) } ] }, @@ -328,11 +308,7 @@ export const snapshotDALFactory = (db: TDbClient) => { const docs = await (tx || db)(TableName.Snapshot) .where(`${TableName.Snapshot}.folderId`, folderId) .join( - (tx || db)(TableName.Snapshot) - .groupBy("folderId") - .max("createdAt") - .select("folderId") - .as("latestVersion"), + (tx || db)(TableName.Snapshot).groupBy("folderId").max("createdAt").select("folderId").as("latestVersion"), (bd) => { bd.on(`${TableName.Snapshot}.folderId`, "latestVersion.folderId").andOn( `${TableName.Snapshot}.createdAt`, 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 72b0eef9f..a443a32f0 100644 --- a/backend/src/ee/services/trusted-ip/trusted-ip-service.ts +++ b/backend/src/ee/services/trusted-ip/trusted-ip-service.ts @@ -28,36 +28,22 @@ export const trustedIpServiceFactory = ({ }: TTrustedIpServiceFactoryDep) => { const listIpsByProjectId = async ({ projectId, actor, actorId }: TProjectPermission) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.IpAllowList - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList); const trustedIps = await trustedIpDAL.find({ projectId }); return trustedIps; }; - const addProjectIp = async ({ - projectId, - actorId, - actor, - ipAddress: ip, - comment, - isActive - }: TCreateIpDTO) => { + const addProjectIp = async ({ projectId, actorId, actor, ipAddress: ip, comment, isActive }: TCreateIpDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.IpAllowList - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); const project = await projectDAL.findById(projectId); const plan = await licenseService.getPlan(project.orgId); if (!plan.ipAllowlisting) throw new BadRequestError({ - message: - "Failed to add IP access range due to plan restriction. Upgrade plan to add IP access range." + message: "Failed to add IP access range due to plan restriction. Upgrade plan to add IP access range." }); const isValidIp = isValidIpOrCidr(ip); @@ -79,26 +65,15 @@ export const trustedIpServiceFactory = ({ return { trustedIp, project }; // for audit log }; - const updateProjectIp = async ({ - projectId, - actorId, - actor, - ipAddress: ip, - comment, - trustedIpId - }: TUpdateIpDTO) => { + const updateProjectIp = async ({ projectId, actorId, actor, ipAddress: ip, comment, trustedIpId }: TUpdateIpDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.IpAllowList - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); const project = await projectDAL.findById(projectId); const plan = await licenseService.getPlan(project.orgId); if (!plan.ipAllowlisting) throw new BadRequestError({ - message: - "Failed to add IP access range due to plan restriction. Upgrade plan to add IP access range." + message: "Failed to add IP access range due to plan restriction. Upgrade plan to add IP access range." }); const isValidIp = isValidIpOrCidr(ip); @@ -124,17 +99,13 @@ export const trustedIpServiceFactory = ({ const deleteProjectIp = async ({ projectId, actorId, actor, trustedIpId }: TDeleteIpDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.IpAllowList - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); const project = await projectDAL.findById(projectId); const plan = await licenseService.getPlan(project.orgId); if (!plan.ipAllowlisting) throw new BadRequestError({ - message: - "Failed to add IP access range due to plan restriction. Upgrade plan to add IP access range." + message: "Failed to add IP access range due to plan restriction. Upgrade plan to add IP access range." }); const [trustedIp] = await trustedIpDAL.delete({ projectId, id: trustedIpId }); diff --git a/backend/src/lib/casl/index.ts b/backend/src/lib/casl/index.ts index c0547a6bb..9e5cb29d3 100644 --- a/backend/src/lib/casl/index.ts +++ b/backend/src/lib/casl/index.ts @@ -24,9 +24,7 @@ export const conditionsMatcher = buildMongoQueryMatcher({ $glob }, { glob }); * Extracts and formats permissions from a CASL Ability object or a raw permission set. */ const extractPermissions = (ability: MongoAbility) => - ability.rules.map( - (permission) => `${permission.action as string}_${permission.subject as string}` - ); + ability.rules.map((permission) => `${permission.action as string}_${permission.subject as string}`); /** * Compares two sets of permissions to determine if the first set is at least as privileged as the second set. diff --git a/backend/src/lib/config/env.ts b/backend/src/lib/config/env.ts index 406d9e297..11c1a3a36 100644 --- a/backend/src/lib/config/env.ts +++ b/backend/src/lib/config/env.ts @@ -38,9 +38,7 @@ const envSchema = z // Telemetry TELEMETRY_ENABLED: zodStrBool.default("true"), POSTHOG_HOST: zpStr(z.string().optional().default("https://app.posthog.com")), - POSTHOG_PROJECT_API_KEY: zpStr( - z.string().optional().default("phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE") - ), + POSTHOG_PROJECT_API_KEY: zpStr(z.string().optional().default("phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE")), LOOPS_API_KEY: zpStr(z.string().optional()), // jwt options AUTH_SECRET: zpStr(z.string()).default(process.env.JWT_AUTH_SECRET), // for those still using old JWT_AUTH_SECRET diff --git a/backend/src/lib/crypto/encryption.ts b/backend/src/lib/crypto/encryption.ts index b3253b4aa..74febccec 100644 --- a/backend/src/lib/crypto/encryption.ts +++ b/backend/src/lib/crypto/encryption.ts @@ -20,11 +20,7 @@ export const BLOCK_SIZE_BYTES_16 = 16; export const decryptSymmetric = ({ ciphertext, iv, tag, key }: TDecryptSymmetricInput): string => { const secretKey = crypto.createSecretKey(key, "base64"); - const decipher = crypto.createDecipheriv( - SecretEncryptionAlgo.AES_256_GCM, - secretKey, - Buffer.from(iv, "base64") - ); + const decipher = crypto.createDecipheriv(SecretEncryptionAlgo.AES_256_GCM, secretKey, Buffer.from(iv, "base64")); decipher.setAuthTag(Buffer.from(tag, "base64")); let cleartext = decipher.update(ciphertext, "base64", "utf8"); cleartext += decipher.final("utf8"); @@ -62,17 +58,8 @@ export const encryptSymmetric128BitHexKeyUTF8 = (plaintext: string, key: string) }; }; -export const decryptSymmetric128BitHexKeyUTF8 = ({ - ciphertext, - iv, - tag, - key -}: TDecryptSymmetricInput): string => { - const decipher = crypto.createDecipheriv( - SecretEncryptionAlgo.AES_256_GCM, - key, - Buffer.from(iv, "base64") - ); +export const decryptSymmetric128BitHexKeyUTF8 = ({ ciphertext, iv, tag, key }: TDecryptSymmetricInput): string => { + const decipher = crypto.createDecipheriv(SecretEncryptionAlgo.AES_256_GCM, key, Buffer.from(iv, "base64")); decipher.setAuthTag(Buffer.from(tag, "base64")); @@ -104,12 +91,7 @@ export type TDecryptAsymmetricInput = { privateKey: string; }; -export const decryptAsymmetric = ({ - ciphertext, - nonce, - publicKey, - privateKey -}: TDecryptAsymmetricInput) => { +export const decryptAsymmetric = ({ ciphertext, nonce, publicKey, privateKey }: TDecryptAsymmetricInput) => { const plaintext: Uint8Array | null = nacl.box.open( naclUtils.decodeBase64(ciphertext), naclUtils.decodeBase64(nonce), diff --git a/backend/src/lib/fn/array.ts b/backend/src/lib/fn/array.ts index 44b7d4f20..1e075101b 100644 --- a/backend/src/lib/fn/array.ts +++ b/backend/src/lib/fn/array.ts @@ -23,10 +23,7 @@ export const groupBy = ( * to convert each item in the list to a comparable identity * value */ -export const unique = ( - array: readonly T[], - toKey?: (item: T) => K -): T[] => { +export const unique = (array: readonly T[], toKey?: (item: T) => K): T[] => { const valueMap = array.reduce( (acc, item) => { const key = toKey ? toKey(item) : (item as unknown as string | number | symbol); diff --git a/backend/src/lib/fn/object.ts b/backend/src/lib/fn/object.ts index 563da728d..87db80343 100644 --- a/backend/src/lib/fn/object.ts +++ b/backend/src/lib/fn/object.ts @@ -2,10 +2,7 @@ * Pick a list of properties from an object * into a new object */ -export const pick = ( - obj: T, - keys: TKeys[] -): Pick => { +export const pick = (obj: T, keys: TKeys[]): Pick => { if (!obj) return {} as Pick; return keys.reduce( (acc, key) => { diff --git a/backend/src/lib/ip/index.ts b/backend/src/lib/ip/index.ts index f14ed4f41..30f710d19 100644 --- a/backend/src/lib/ip/index.ts +++ b/backend/src/lib/ip/index.ts @@ -111,13 +111,7 @@ export type TIp = { /** * Validates the IP address [ipAddress] against the trusted IPs [trustedIps]. */ -export const checkIPAgainstBlocklist = ({ - ipAddress, - trustedIps -}: { - ipAddress: string; - trustedIps: TIp[]; -}) => { +export const checkIPAgainstBlocklist = ({ ipAddress, trustedIps }: { ipAddress: string; trustedIps: TIp[] }) => { const blockList = new net.BlockList(); for (const trustedIp of trustedIps) { diff --git a/backend/src/lib/knex/index.ts b/backend/src/lib/knex/index.ts index 92479c978..37fae624e 100644 --- a/backend/src/lib/knex/index.ts +++ b/backend/src/lib/knex/index.ts @@ -41,11 +41,7 @@ export type TFindOpt = { // 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) => ({ transaction: async (cb: (tx: Knex) => Promise) => db.transaction(async (trx) => { const res = await cb(trx); @@ -78,9 +74,7 @@ export const ormify = ( if (limit) void query.limit(limit); if (offset) void query.offset(offset); if (sort) { - void query.orderBy( - sort.map(([column, order, nulls]) => ({ column: column as string, order, nulls })) - ); + void query.orderBy(sort.map(([column, order, nulls]) => ({ column: column as string, order, nulls }))); } const res = await query; return res; @@ -120,11 +114,7 @@ export const ormify = ( throw new DatabaseError({ error, name: "Update by id" }); } }, - update: async ( - filter: TFindFilter, - data: Tables[Tname]["update"], - tx?: Knex - ) => { + update: async (filter: TFindFilter, data: Tables[Tname]["update"], tx?: Knex) => { try { const res = await (tx || db)(tableName) .where(buildFindFilter(filter)) @@ -148,10 +138,7 @@ export const ormify = ( }, delete: async (filter: TFindFilter, tx?: Knex) => { try { - const res = await (tx || db)(tableName) - .where(buildFindFilter(filter)) - .delete() - .returning("*"); + const res = await (tx || db)(tableName).where(buildFindFilter(filter)).delete().returning("*"); return res; } catch (error) { throw new DatabaseError({ error, name: "Delete" }); diff --git a/backend/src/lib/zod/index.ts b/backend/src/lib/zod/index.ts index 629f42f68..a3cded66b 100644 --- a/backend/src/lib/zod/index.ts +++ b/backend/src/lib/zod/index.ts @@ -1,10 +1,7 @@ import { z, ZodTypeAny } from "zod"; // this is a patched zod string to remove empty string to undefined -export const zpStr = ( - schema: T, - opt: { stripNull: boolean } = { stripNull: true } -) => +export const zpStr = (schema: T, opt: { stripNull: boolean } = { stripNull: true }) => z.preprocess((val) => { if (opt.stripNull && val === null) return undefined; if (typeof val !== "string") return val; diff --git a/backend/src/queue/queue-service.ts b/backend/src/queue/queue-service.ts index 6065248d7..c46b60ca9 100644 --- a/backend/src/queue/queue-service.ts +++ b/backend/src/queue/queue-service.ts @@ -74,23 +74,18 @@ export const queueServiceFactory = (redisUrl: string) => { const start = ( name: T, - jobFn: ( - job: Job - ) => Promise + jobFn: (job: Job) => Promise ) => { if (queueContainer[name]) { throw new Error(`${name} queue is already initialized`); } - queueContainer[name] = new Queue( - name as string, - { connection } - ); - workerContainer[name] = new Worker< - TQueueJobTypes[T]["payload"], - void, - TQueueJobTypes[T]["name"] - >(name, jobFn, { connection }); + queueContainer[name] = new Queue(name as string, { + connection + }); + workerContainer[name] = new Worker(name, jobFn, { + connection + }); }; const listen = < diff --git a/backend/src/server/plugins/auth/inject-identity.ts b/backend/src/server/plugins/auth/inject-identity.ts index 7411ee640..04d4cbe0e 100644 --- a/backend/src/server/plugins/auth/inject-identity.ts +++ b/backend/src/server/plugins/auth/inject-identity.ts @@ -5,12 +5,7 @@ import jwt, { JwtPayload } from "jsonwebtoken"; import { TServiceTokens, TUsers } from "@app/db/schemas"; import { getConfig } from "@app/lib/config/env"; import { UnauthorizedError } from "@app/lib/errors"; -import { - ActorType, - AuthMode, - AuthModeJwtTokenPayload, - AuthTokenType -} from "@app/services/auth/auth-type"; +import { ActorType, AuthMode, AuthModeJwtTokenPayload, AuthTokenType } from "@app/services/auth/auth-type"; import { TIdentityAccessTokenJwtPayload } from "@app/services/identity-access-token/identity-access-token-types"; export type TAuthMode = @@ -87,16 +82,12 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => { switch (authMode) { case AuthMode.JWT: { - const { user, tokenVersionId } = - await server.services.authToken.fnValidateJwtIdentity(token); + const { user, tokenVersionId } = await server.services.authToken.fnValidateJwtIdentity(token); req.auth = { authMode: AuthMode.JWT, user, userId: user.id, tokenVersionId, actor }; break; } case AuthMode.IDENTITY_ACCESS_TOKEN: { - const identity = await server.services.identityAccessToken.fnValidateIdentityAccessToken( - token, - req.realIp - ); + const identity = await server.services.identityAccessToken.fnValidateIdentityAccessToken(token, req.realIp); req.auth = { authMode: AuthMode.IDENTITY_ACCESS_TOKEN, actor, diff --git a/backend/src/server/plugins/auth/verify-auth.ts b/backend/src/server/plugins/auth/verify-auth.ts index c854e28cc..a1274f356 100644 --- a/backend/src/server/plugins/auth/verify-auth.ts +++ b/backend/src/server/plugins/auth/verify-auth.ts @@ -7,8 +7,7 @@ export const verifyAuth = (authStrats: AuthMode[]) => (req: T, _res: FastifyReply, done: HookHandlerDoneFunction) => { if (!Array.isArray(authStrats)) throw new Error("Auth strategy must be array"); - if (!req.auth) - throw new UnauthorizedError({ name: "Unauthorized access", message: "Token missing" }); + if (!req.auth) throw new UnauthorizedError({ name: "Unauthorized access", message: "Token missing" }); const isAccessAllowed = authStrats.some((strat) => strat === req.auth.authMode); if (!isAccessAllowed) { diff --git a/backend/src/server/plugins/error-handler.ts b/backend/src/server/plugins/error-handler.ts index 977d71d90..8587c93bd 100644 --- a/backend/src/server/plugins/error-handler.ts +++ b/backend/src/server/plugins/error-handler.ts @@ -2,12 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import fastifyPlugin from "fastify-plugin"; import { ZodError } from "zod"; -import { - BadRequestError, - DatabaseError, - InternalServerError, - UnauthorizedError -} from "@app/lib/errors"; +import { BadRequestError, DatabaseError, InternalServerError, UnauthorizedError } from "@app/lib/errors"; export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider) => { server.setErrorHandler((error, req, res) => { @@ -17,13 +12,9 @@ export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider } else if (error instanceof UnauthorizedError) { void res.status(403).send({ statusCode: 403, message: error.message, error: error.name }); } else if (error instanceof DatabaseError || error instanceof InternalServerError) { - void res - .status(500) - .send({ statusCode: 500, message: "Something went wrong", error: error.name }); + void res.status(500).send({ statusCode: 500, message: "Something went wrong", error: error.name }); } else if (error instanceof ZodError) { - void res - .status(403) - .send({ statusCode: 403, error: "ValidationFailure", message: error.issues }); + void res.status(403).send({ statusCode: 403, error: "ValidationFailure", message: error.issues }); } else if (error instanceof ForbiddenError) { void res.status(401).send({ statusCode: 401, diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index be754097a..113060b65 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -92,10 +92,7 @@ import { serviceTokenDALFactory } from "@app/services/service-token/service-toke import { serviceTokenServiceFactory } from "@app/services/service-token/service-token-service"; import { TSmtpService } from "@app/services/smtp/smtp-service"; import { superAdminDALFactory } from "@app/services/super-admin/super-admin-dal"; -import { - getServerCfg, - superAdminServiceFactory -} from "@app/services/super-admin/super-admin-service"; +import { getServerCfg, superAdminServiceFactory } from "@app/services/super-admin/super-admin-service"; import { telemetryServiceFactory } from "@app/services/telemetry/telemetry-service"; import { userDALFactory } from "@app/services/user/user-dal"; import { userServiceFactory } from "@app/services/user/user-service"; @@ -112,11 +109,7 @@ import { registerV3Routes } from "./v3"; export const registerRoutes = async ( server: FastifyZodProvider, - { - db, - smtp: smtpService, - queue: queueService - }: { db: Knex; smtp: TSmtpService; queue: TQueueServiceFactory } + { db, smtp: smtpService, queue: queueService }: { db: Knex; smtp: TSmtpService; queue: TQueueServiceFactory } ) => { await server.register(registerSecretScannerGhApp, { prefix: "/ss-webhook" }); diff --git a/backend/src/server/routes/v1/auth-router.ts b/backend/src/server/routes/v1/auth-router.ts index 0d8621727..2dc0a5d50 100644 --- a/backend/src/server/routes/v1/auth-router.ts +++ b/backend/src/server/routes/v1/auth-router.ts @@ -5,11 +5,7 @@ import { getConfig } from "@app/lib/config/env"; import { BadRequestError, UnauthorizedError } from "@app/lib/errors"; import { authRateLimit } from "@app/server/config/rateLimiter"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; -import { - AuthMode, - AuthModeRefreshJwtTokenPayload, - AuthTokenType -} from "@app/services/auth/auth-type"; +import { AuthMode, AuthModeRefreshJwtTokenPayload, AuthTokenType } from "@app/services/auth/auth-type"; export const registerAuthRoutes = async (server: FastifyZodProvider) => { server.route({ @@ -74,10 +70,7 @@ export const registerAuthRoutes = async (server: FastifyZodProvider) => { message: "Failed to find refresh token" }); - const decodedToken = jwt.verify( - refreshToken, - appCfg.AUTH_SECRET - ) as AuthModeRefreshJwtTokenPayload; + const decodedToken = jwt.verify(refreshToken, appCfg.AUTH_SECRET) as AuthModeRefreshJwtTokenPayload; if (decodedToken.authTokenType !== AuthTokenType.REFRESH_TOKEN) throw new UnauthorizedError({ message: "Invalid token", name: "Auth token route" }); @@ -85,8 +78,7 @@ export const registerAuthRoutes = async (server: FastifyZodProvider) => { decodedToken.tokenVersionId, decodedToken.userId ); - if (!tokenVersion) - throw new UnauthorizedError({ message: "Invalid token", name: "Auth token route" }); + if (!tokenVersion) throw new UnauthorizedError({ message: "Invalid token", name: "Auth token route" }); if (decodedToken.refreshVersion !== tokenVersion.refreshVersion) throw new UnauthorizedError({ message: "Invalid token", name: "Auth token route" }); diff --git a/backend/src/server/routes/v1/identity-access-token-router.ts b/backend/src/server/routes/v1/identity-access-token-router.ts index b39fe08a2..4ddf7b74a 100644 --- a/backend/src/server/routes/v1/identity-access-token-router.ts +++ b/backend/src/server/routes/v1/identity-access-token-router.ts @@ -18,10 +18,9 @@ export const registerIdentityAccessTokenRouter = async (server: FastifyZodProvid } }, handler: async (req) => { - const { accessToken, identityAccessToken } = - await server.services.identityAccessToken.renewAccessToken({ - accessToken: req.body.accessToken - }); + const { accessToken, identityAccessToken } = await server.services.identityAccessToken.renewAccessToken({ + accessToken: req.body.accessToken + }); return { accessToken, tokenType: "Bearer" as const, diff --git a/backend/src/server/routes/v1/identity-ua.ts b/backend/src/server/routes/v1/identity-ua.ts index 1c7c6e5f7..d92d2a61a 100644 --- a/backend/src/server/routes/v1/identity-ua.ts +++ b/backend/src/server/routes/v1/identity-ua.ts @@ -39,11 +39,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { }, handler: async (req) => { const { identityUa, accessToken, identityAccessToken, validClientSecretInfo } = - await server.services.identityUa.login( - req.body.clientId, - req.body.clientSecret, - req.realIp - ); + await server.services.identityUa.login(req.body.clientId, req.body.clientSecret, req.realIp); await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, @@ -128,10 +124,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { identityId: identityUniversalAuth.identityId, accessTokenTTL: identityUniversalAuth.accessTokenTTL, accessTokenMaxTTL: identityUniversalAuth.accessTokenMaxTTL, - accessTokenTrustedIps: - identityUniversalAuth.accessTokenTrustedIps as TIdentityTrustedIp[], - clientSecretTrustedIps: - identityUniversalAuth.clientSecretTrustedIps as TIdentityTrustedIp[], + accessTokenTrustedIps: identityUniversalAuth.accessTokenTrustedIps as TIdentityTrustedIp[], + clientSecretTrustedIps: identityUniversalAuth.clientSecretTrustedIps as TIdentityTrustedIp[], accessTokenNumUsesLimit: identityUniversalAuth.accessTokenNumUsesLimit } } @@ -197,10 +191,8 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { identityId: identityUniversalAuth.identityId, accessTokenTTL: identityUniversalAuth.accessTokenTTL, accessTokenMaxTTL: identityUniversalAuth.accessTokenMaxTTL, - accessTokenTrustedIps: - identityUniversalAuth.accessTokenTrustedIps as TIdentityTrustedIp[], - clientSecretTrustedIps: - identityUniversalAuth.clientSecretTrustedIps as TIdentityTrustedIp[], + accessTokenTrustedIps: identityUniversalAuth.accessTokenTrustedIps as TIdentityTrustedIp[], + clientSecretTrustedIps: identityUniversalAuth.clientSecretTrustedIps as TIdentityTrustedIp[], accessTokenNumUsesLimit: identityUniversalAuth.accessTokenNumUsesLimit } } @@ -267,13 +259,12 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { } }, handler: async (req) => { - const { clientSecret, clientSecretData, orgId } = - await server.services.identityUa.createUaClientSecret({ - actor: req.permission.type, - actorId: req.permission.id, - identityId: req.params.identityId, - ...req.body - }); + const { clientSecret, clientSecretData, orgId } = await server.services.identityUa.createUaClientSecret({ + actor: req.permission.type, + actorId: req.permission.id, + identityId: req.params.identityId, + ...req.body + }); await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, @@ -306,12 +297,11 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => { } }, handler: async (req) => { - const { clientSecrets: clientSecretData, orgId } = - await server.services.identityUa.getUaClientSecrets({ - actor: req.permission.type, - actorId: req.permission.id, - identityId: req.params.identityId - }); + const { clientSecrets: clientSecretData, orgId } = await server.services.identityUa.getUaClientSecrets({ + actor: req.permission.type, + actorId: req.permission.id, + identityId: req.params.identityId + }); await server.services.auditLog.createAuditLog({ ...req.auditLogInfo, diff --git a/backend/src/server/routes/v1/organization-router.ts b/backend/src/server/routes/v1/organization-router.ts index f5fd06c87..1d74e8b1a 100644 --- a/backend/src/server/routes/v1/organization-router.ts +++ b/backend/src/server/routes/v1/organization-router.ts @@ -1,11 +1,6 @@ import { z } from "zod"; -import { - IncidentContactsSchema, - OrganizationsSchema, - OrgMembershipsSchema, - UsersSchema -} from "@app/db/schemas"; +import { IncidentContactsSchema, OrganizationsSchema, OrgMembershipsSchema, UsersSchema } from "@app/db/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; @@ -42,10 +37,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const organization = await server.services.org.findOrganizationById( - req.permission.id, - req.params.organizationId - ); + const organization = await server.services.org.findOrganizationById(req.permission.id, req.params.organizationId); return { organization }; } }); @@ -76,10 +68,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const users = await server.services.org.findAllOrgMembers( - req.permission.id, - req.params.organizationId - ); + const users = await server.services.org.findAllOrgMembers(req.permission.id, req.params.organizationId); return { users }; } }); diff --git a/backend/src/server/routes/v1/password-router.ts b/backend/src/server/routes/v1/password-router.ts index b3a9044c6..d5c5054df 100644 --- a/backend/src/server/routes/v1/password-router.ts +++ b/backend/src/server/routes/v1/password-router.ts @@ -119,10 +119,7 @@ export const registerPasswordRouter = async (server: FastifyZodProvider) => { } }, handler: async (req) => { - const { token, user } = await server.services.password.verifyPasswordResetEmail( - req.body.email, - req.body.code - ); + const { token, user } = await server.services.password.verifyPasswordResetEmail(req.body.email, req.body.code); return { message: "Successfully verified email", @@ -183,9 +180,7 @@ export const registerPasswordRouter = async (server: FastifyZodProvider) => { }, handler: async (req) => { const token = validateSignUpAuthorization(req.headers.authorization as string, "", false)!; - const backupPrivateKey = await server.services.password.getBackupPrivateKeyOfUser( - token.userId - ); + const backupPrivateKey = await server.services.password.getBackupPrivateKeyOfUser(token.userId); if (!backupPrivateKey) throw new Error("Failed to find backup key"); return { message: "Successfully fetched backup private key", backupPrivateKey }; diff --git a/backend/src/server/routes/v1/project-membership-router.ts b/backend/src/server/routes/v1/project-membership-router.ts index bacfcb1bb..7d28f470a 100644 --- a/backend/src/server/routes/v1/project-membership-router.ts +++ b/backend/src/server/routes/v1/project-membership-router.ts @@ -1,11 +1,6 @@ import { z } from "zod"; -import { - OrgMembershipsSchema, - ProjectMembershipsSchema, - UserEncryptionKeysSchema, - UsersSchema -} from "@app/db/schemas"; +import { OrgMembershipsSchema, ProjectMembershipsSchema, UserEncryptionKeysSchema, UsersSchema } from "@app/db/schemas"; import { EventType } from "@app/ee/services/audit-log/audit-log-types"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMode } from "@app/services/auth/auth-type"; diff --git a/backend/src/server/routes/v1/secret-folder-router.ts b/backend/src/server/routes/v1/secret-folder-router.ts index c71767868..4a152f52e 100644 --- a/backend/src/server/routes/v1/secret-folder-router.ts +++ b/backend/src/server/routes/v1/secret-folder-router.ts @@ -25,12 +25,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const path = req.body.path || req.body.directory; const folder = await server.services.folder.createFolder({ @@ -79,12 +74,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const path = req.body.path || req.body.directory; const { folder, old } = await server.services.folder.updateFolder({ @@ -133,12 +123,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const path = req.body.path || req.body.directory; const folder = await server.services.folder.deleteFolder({ @@ -183,12 +168,7 @@ export const registerSecretFolderRouter = async (server: FastifyZodProvider) => }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const path = req.query.path || req.query.directory; const folders = await server.services.folder.getFolders({ diff --git a/backend/src/server/routes/v1/secret-import-router.ts b/backend/src/server/routes/v1/secret-import-router.ts index f27f9e0c2..80f980a90 100644 --- a/backend/src/server/routes/v1/secret-import-router.ts +++ b/backend/src/server/routes/v1/secret-import-router.ts @@ -31,12 +31,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const secretImport = await server.services.secretImport.createImport({ actorId: req.permission.id, @@ -97,12 +92,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const secretImport = await server.services.secretImport.updateImport({ actorId: req.permission.id, @@ -155,12 +145,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const secretImport = await server.services.secretImport.deleteImport({ actorId: req.permission.id, @@ -211,12 +196,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const secretImports = await server.services.secretImport.getImports({ actorId: req.permission.id, @@ -268,12 +248,7 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) => }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const importedSecrets = await server.services.secretImport.getSecretsFromImports({ actorId: req.permission.id, diff --git a/backend/src/server/routes/v1/sso-router.ts b/backend/src/server/routes/v1/sso-router.ts index ed882041b..9c7c85b04 100644 --- a/backend/src/server/routes/v1/sso-router.ts +++ b/backend/src/server/routes/v1/sso-router.ts @@ -27,9 +27,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { await server.register(passport.initialize()); await server.register(passport.secureSession()); // passport oauth strategy for Google - const isGoogleOauthActive = Boolean( - appCfg.CLIENT_ID_GOOGLE_LOGIN && appCfg.CLIENT_SECRET_GOOGLE_LOGIN - ); + const isGoogleOauthActive = Boolean(appCfg.CLIENT_ID_GOOGLE_LOGIN && appCfg.CLIENT_SECRET_GOOGLE_LOGIN); if (isGoogleOauthActive) { passport.use( new GoogleStrategy( @@ -70,9 +68,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { } // Passport strategy for Github - const isGithubOauthActive = Boolean( - appCfg.CLIENT_SECRET_GITHUB_LOGIN && appCfg.CLIENT_ID_GITHUB_LOGIN - ); + const isGithubOauthActive = Boolean(appCfg.CLIENT_SECRET_GITHUB_LOGIN && appCfg.CLIENT_ID_GITHUB_LOGIN); if (isGithubOauthActive) { passport.use( new GitHubStrategy( @@ -109,9 +105,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { // passport strategy for gitlab const isGitlabOauthActive = Boolean( - appCfg.CLIENT_ID_GITLAB_LOGIN && - appCfg.CLIENT_SECRET_GITLAB_LOGIN && - appCfg.CLIENT_GITLAB_LOGIN_URL + appCfg.CLIENT_ID_GITLAB_LOGIN && appCfg.CLIENT_SECRET_GITLAB_LOGIN && appCfg.CLIENT_GITLAB_LOGIN_URL ); if (isGitlabOauthActive) { passport.use( @@ -180,15 +174,11 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { handler: (req, res) => { if (req.passportUser.isUserCompleted) { return res.redirect( - `${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent( - req.passportUser.providerAuthToken - )}` + `${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}` ); } return res.redirect( - `${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent( - req.passportUser.providerAuthToken - )}` + `${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}` ); } }); @@ -225,15 +215,11 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { handler: (req, res) => { if (req.passportUser.isUserCompleted) { return res.redirect( - `${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent( - req.passportUser.providerAuthToken - )}` + `${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}` ); } return res.redirect( - `${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent( - req.passportUser.providerAuthToken - )}` + `${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}` ); } }); @@ -272,15 +258,11 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => { handler: (req, res) => { if (req.passportUser.isUserCompleted) { return res.redirect( - `${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent( - req.passportUser.providerAuthToken - )}` + `${appCfg.SITE_URL}/login/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}` ); } return res.redirect( - `${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent( - req.passportUser.providerAuthToken - )}` + `${appCfg.SITE_URL}/signup/sso?token=${encodeURIComponent(req.passportUser.providerAuthToken)}` ); } }); diff --git a/backend/src/server/routes/v1/user-action-router.ts b/backend/src/server/routes/v1/user-action-router.ts index 5ce66eb79..c730cdb91 100644 --- a/backend/src/server/routes/v1/user-action-router.ts +++ b/backend/src/server/routes/v1/user-action-router.ts @@ -21,10 +21,7 @@ export const registerUserActionRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const userAction = await server.services.user.createUserAction( - req.permission.id, - req.body.action - ); + const userAction = await server.services.user.createUserAction(req.permission.id, req.body.action); return { userAction, message: "Successfully recorded user action" }; } }); @@ -44,10 +41,7 @@ export const registerUserActionRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const userAction = await server.services.user.getUserAction( - req.permission.id, - req.query.action - ); + const userAction = await server.services.user.getUserAction(req.permission.id, req.query.action); return { userAction }; } }); diff --git a/backend/src/server/routes/v2/mfa-router.ts b/backend/src/server/routes/v2/mfa-router.ts index 6ba5a9f49..cbe7f1cbf 100644 --- a/backend/src/server/routes/v2/mfa-router.ts +++ b/backend/src/server/routes/v2/mfa-router.ts @@ -22,8 +22,7 @@ export const registerMfaRouter = async (server: FastifyZodProvider) => { } const decodedToken = jwt.verify(token, cfg.AUTH_SECRET) as AuthModeMfaJwtTokenPayload; - if (decodedToken.authTokenType !== AuthTokenType.MFA_TOKEN) - throw new Error("Unauthorized access"); + if (decodedToken.authTokenType !== AuthTokenType.MFA_TOKEN) throw new Error("Unauthorized access"); const user = await server.store.user.findById(decodedToken.userId); if (!user) throw new Error("User not found"); diff --git a/backend/src/server/routes/v2/organization-router.ts b/backend/src/server/routes/v2/organization-router.ts index d2fa7d450..667ef406e 100644 --- a/backend/src/server/routes/v2/organization-router.ts +++ b/backend/src/server/routes/v2/organization-router.ts @@ -1,11 +1,6 @@ import { z } from "zod"; -import { - OrganizationsSchema, - OrgMembershipsSchema, - UserEncryptionKeysSchema, - UsersSchema -} from "@app/db/schemas"; +import { OrganizationsSchema, OrgMembershipsSchema, UserEncryptionKeysSchema, UsersSchema } from "@app/db/schemas"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { ActorType, AuthMode } from "@app/services/auth/auth-type"; @@ -38,10 +33,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { handler: async (req) => { if (req.auth.actor !== ActorType.USER) return; - const users = await server.services.org.findAllOrgMembers( - req.permission.id, - req.params.organizationId - ); + const users = await server.services.org.findAllOrgMembers(req.permission.id, req.params.organizationId); return { users }; } }); diff --git a/backend/src/server/routes/v2/user-router.ts b/backend/src/server/routes/v2/user-router.ts index cf34a9522..8061aa0e5 100644 --- a/backend/src/server/routes/v2/user-router.ts +++ b/backend/src/server/routes/v2/user-router.ts @@ -1,11 +1,6 @@ import { z } from "zod"; -import { - AuthTokenSessionsSchema, - OrganizationsSchema, - UserEncryptionKeysSchema, - UsersSchema -} from "@app/db/schemas"; +import { AuthTokenSessionsSchema, OrganizationsSchema, UserEncryptionKeysSchema, UsersSchema } from "@app/db/schemas"; import { ApiKeysSchema } from "@app/db/schemas/api-keys"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { AuthMethod, AuthMode } from "@app/services/auth/auth-type"; @@ -26,10 +21,7 @@ export const registerUserRouter = async (server: FastifyZodProvider) => { }, preHandler: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]), handler: async (req) => { - const user = await server.services.user.toggleUserMfa( - req.permission.id, - req.body.isMfaEnabled - ); + const user = await server.services.user.toggleUserMfa(req.permission.id, req.body.isMfaEnabled); return { user }; } }); @@ -50,11 +42,7 @@ export const registerUserRouter = async (server: FastifyZodProvider) => { }, preHandler: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]), handler: async (req) => { - const user = await server.services.user.updateUserName( - req.permission.id, - req.body.firstName, - req.body.lastName - ); + const user = await server.services.user.updateUserName(req.permission.id, req.body.firstName, req.body.lastName); return { user }; } }); @@ -74,10 +62,7 @@ export const registerUserRouter = async (server: FastifyZodProvider) => { }, preHandler: verifyAuth([AuthMode.JWT, AuthMode.API_KEY]), handler: async (req) => { - const user = await server.services.user.updateAuthMethods( - req.permission.id, - req.body.authMethods - ); + const user = await server.services.user.updateAuthMethods(req.permission.id, req.body.authMethods); return { user }; } }); @@ -131,11 +116,7 @@ export const registerUserRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const apiKeys = await server.services.apiKey.createApiKey( - req.permission.id, - req.body.name, - req.body.expiresIn - ); + const apiKeys = await server.services.apiKey.createApiKey(req.permission.id, req.body.name, req.body.expiresIn); return apiKeys; } }); @@ -155,10 +136,7 @@ export const registerUserRouter = async (server: FastifyZodProvider) => { }, onRequest: verifyAuth([AuthMode.JWT]), handler: async (req) => { - const apiKeyData = await server.services.apiKey.deleteApiKey( - req.permission.id, - req.params.apiKeyDataId - ); + const apiKeyData = await server.services.apiKey.deleteApiKey(req.permission.id, req.params.apiKeyDataId); return { apiKeyData }; } }); diff --git a/backend/src/server/routes/v3/secret-router.ts b/backend/src/server/routes/v3/secret-router.ts index db14eb0f6..8df8533b8 100644 --- a/backend/src/server/routes/v3/secret-router.ts +++ b/backend/src/server/routes/v3/secret-router.ts @@ -61,12 +61,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { // just for delivery hero usecase let { secretPath, environment, workspaceId } = req.query; @@ -80,8 +75,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { } } - if (!workspaceId || !environment) - throw new BadRequestError({ message: "Missing workspace id or environment" }); + if (!workspaceId || !environment) throw new BadRequestError({ message: "Missing workspace id or environment" }); const { secrets, imports } = await server.services.secret.getSecretsRaw({ actorId: req.permission.id, @@ -144,12 +138,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { let { secretPath, environment, workspaceId } = req.query; if (req.auth.actor === ActorType.SERVICE) { @@ -162,8 +151,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { } } - if (!workspaceId || !environment) - throw new BadRequestError({ message: "Missing workspace id or environment" }); + if (!workspaceId || !environment) throw new BadRequestError({ message: "Missing workspace id or environment" }); const secret = await server.services.secret.getSecretByNameRaw({ actorId: req.permission.id, @@ -218,9 +206,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { workspaceId: z.string().trim(), environment: z.string().trim(), secretPath: z.string().trim().default("/").transform(removeTrailingSlash), - secretValue: z - .string() - .transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())), + secretValue: z.string().transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())), secretComment: z.string().trim().optional().default(""), skipMultilineEncoding: z.boolean().optional(), type: z.nativeEnum(SecretType).default(SecretType.Shared) @@ -231,12 +217,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const secret = await server.services.secret.createSecretRaw({ actorId: req.permission.id, @@ -293,9 +274,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { body: z.object({ workspaceId: z.string().trim(), environment: z.string().trim(), - secretValue: z - .string() - .transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())), + secretValue: z.string().transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim())), secretPath: z.string().trim().default("/").transform(removeTrailingSlash), skipMultilineEncoding: z.boolean().optional(), type: z.nativeEnum(SecretType).default(SecretType.Shared) @@ -306,12 +285,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const secret = await server.services.secret.updateSecretRaw({ actorId: req.permission.id, @@ -375,12 +349,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const secret = await server.services.secret.deleteSecretRaw({ actorId: req.permission.id, @@ -474,12 +443,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const { secrets, imports } = await server.services.secret.getSecrets({ actorId: req.permission.id, @@ -549,12 +513,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const secret = await server.services.secret.getSecretByName({ actorId: req.permission.id, @@ -634,18 +593,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) ) }), - z - .object({ approval: SecretApprovalRequestsSchema }) - .describe("When secret protection policy is enabled") + z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled") ]) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const { workspaceId: projectId, @@ -673,32 +625,31 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { projectId }); if (policy) { - const approval = - await server.services.secretApprovalRequest.generateSecretApprovalRequest({ - actorId: req.permission.id, - actor: req.permission.type, - secretPath, - environment, - projectId, - policy, - data: { - [CommitType.Create]: [ - { - secretName: req.params.secretName, - secretValueCiphertext, - secretValueIV, - secretValueTag, - secretCommentIV, - secretCommentTag, - secretCommentCiphertext, - skipMultilineEncoding, - secretKeyTag, - secretKeyCiphertext, - secretKeyIV - } - ] - } - }); + const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ + actorId: req.permission.id, + actor: req.permission.type, + secretPath, + environment, + projectId, + policy, + data: { + [CommitType.Create]: [ + { + secretName: req.params.secretName, + secretValueCiphertext, + secretValueIV, + secretValueTag, + secretCommentIV, + secretCommentTag, + secretCommentCiphertext, + skipMultilineEncoding, + secretKeyTag, + secretKeyCiphertext, + secretKeyIV + } + ] + } + }); await server.services.auditLog.createAuditLog({ projectId: req.body.workspaceId, @@ -810,18 +761,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) ) }), - z - .object({ approval: SecretApprovalRequestsSchema }) - .describe("When secret protection policy is enabled") + z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled") ]) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const { secretValueCiphertext, @@ -854,34 +798,33 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { projectId }); if (policy) { - const approval = - await server.services.secretApprovalRequest.generateSecretApprovalRequest({ - actorId: req.permission.id, - actor: req.permission.type, - secretPath, - environment, - projectId, - policy, - data: { - [CommitType.Update]: [ - { - secretName: req.params.secretName, - newSecretName, - secretValueCiphertext, - secretValueIV, - secretValueTag, - secretCommentIV, - secretCommentTag, - secretCommentCiphertext, - skipMultilineEncoding, - secretKeyTag, - secretKeyCiphertext, - secretKeyIV, - tagIds: tags - } - ] - } - }); + const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ + actorId: req.permission.id, + actor: req.permission.type, + secretPath, + environment, + projectId, + policy, + data: { + [CommitType.Update]: [ + { + secretName: req.params.secretName, + newSecretName, + secretValueCiphertext, + secretValueIV, + secretValueTag, + secretCommentIV, + secretCommentTag, + secretCommentCiphertext, + skipMultilineEncoding, + secretKeyTag, + secretKeyCiphertext, + secretKeyIV, + tagIds: tags + } + ] + } + }); await server.services.auditLog.createAuditLog({ projectId: req.body.workspaceId, @@ -980,18 +923,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { }) ) }), - z - .object({ approval: SecretApprovalRequestsSchema }) - .describe("When secret protection policy is enabled") + z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled") ]) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const { secretPath, type, workspaceId: projectId, secretId, environment } = req.body; if (req.body.type !== SecretType.Personal && req.permission.type === ActorType.USER) { @@ -1003,22 +939,21 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { projectId }); if (policy) { - const approval = - await server.services.secretApprovalRequest.generateSecretApprovalRequest({ - actorId: req.permission.id, - actor: req.permission.type, - secretPath, - environment, - projectId, - policy, - data: { - [CommitType.Delete]: [ - { - secretName: req.params.secretName - } - ] - } - }); + const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ + actorId: req.permission.id, + actor: req.permission.type, + secretPath, + environment, + projectId, + policy, + data: { + [CommitType.Delete]: [ + { + secretName: req.params.secretName + } + ] + } + }); await server.services.auditLog.createAuditLog({ projectId: req.body.workspaceId, @@ -1110,18 +1045,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { z.object({ secrets: SecretsSchema.omit({ secretBlindIndex: true }).array() }), - z - .object({ approval: SecretApprovalRequestsSchema }) - .describe("When secret protection policy is enabled") + z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled") ]) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const { environment, workspaceId: projectId, secretPath, secrets: inputSecrets } = req.body; if (req.permission.type === ActorType.USER) { @@ -1133,18 +1061,17 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { projectId }); if (policy) { - const approval = - await server.services.secretApprovalRequest.generateSecretApprovalRequest({ - actorId: req.permission.id, - actor: req.permission.type, - secretPath, - environment, - projectId, - policy, - data: { - [CommitType.Create]: inputSecrets.filter(({ type }) => type === "shared") - } - }); + const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ + actorId: req.permission.id, + actor: req.permission.type, + secretPath, + environment, + projectId, + policy, + data: { + [CommitType.Create]: inputSecrets.filter(({ type }) => type === "shared") + } + }); await server.services.auditLog.createAuditLog({ projectId: req.body.workspaceId, @@ -1236,18 +1163,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { z.object({ secrets: SecretsSchema.omit({ secretBlindIndex: true }).array() }), - z - .object({ approval: SecretApprovalRequestsSchema }) - .describe("When secret protection policy is enabled") + z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled") ]) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const { environment, workspaceId: projectId, secretPath, secrets: inputSecrets } = req.body; if (req.permission.type === ActorType.USER) { @@ -1259,18 +1179,17 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { projectId }); if (policy) { - const approval = - await server.services.secretApprovalRequest.generateSecretApprovalRequest({ - actorId: req.permission.id, - actor: req.permission.type, - secretPath, - environment, - projectId, - policy, - data: { - [CommitType.Update]: inputSecrets.filter(({ type }) => type === "shared") - } - }); + const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ + actorId: req.permission.id, + actor: req.permission.type, + secretPath, + environment, + projectId, + policy, + data: { + [CommitType.Update]: inputSecrets.filter(({ type }) => type === "shared") + } + }); await server.services.auditLog.createAuditLog({ projectId: req.body.workspaceId, @@ -1350,18 +1269,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { z.object({ secrets: SecretsSchema.omit({ secretBlindIndex: true }).array() }), - z - .object({ approval: SecretApprovalRequestsSchema }) - .describe("When secret protection policy is enabled") + z.object({ approval: SecretApprovalRequestsSchema }).describe("When secret protection policy is enabled") ]) } }, - onRequest: verifyAuth([ - AuthMode.JWT, - AuthMode.API_KEY, - AuthMode.SERVICE_TOKEN, - AuthMode.IDENTITY_ACCESS_TOKEN - ]), + onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), handler: async (req) => { const { environment, workspaceId: projectId, secretPath, secrets: inputSecrets } = req.body; if (req.permission.type === ActorType.USER) { @@ -1373,18 +1285,17 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => { projectId }); if (policy) { - const approval = - await server.services.secretApprovalRequest.generateSecretApprovalRequest({ - actorId: req.permission.id, - actor: req.permission.type, - secretPath, - environment, - projectId, - policy, - data: { - [CommitType.Delete]: inputSecrets.filter(({ type }) => type === "shared") - } - }); + const approval = await server.services.secretApprovalRequest.generateSecretApprovalRequest({ + actorId: req.permission.id, + actor: req.permission.type, + secretPath, + environment, + projectId, + policy, + data: { + [CommitType.Delete]: inputSecrets.filter(({ type }) => type === "shared") + } + }); await server.services.auditLog.createAuditLog({ projectId: req.body.workspaceId, ...req.auditLogInfo, diff --git a/backend/src/server/routes/v3/signup-router.ts b/backend/src/server/routes/v3/signup-router.ts index 62f197b54..064068507 100644 --- a/backend/src/server/routes/v3/signup-router.ts +++ b/backend/src/server/routes/v3/signup-router.ts @@ -48,10 +48,7 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { } }, handler: async (req) => { - const { token, user } = await server.services.signup.verifyEmailSignup( - req.body.email, - req.body.code - ); + const { token, user } = await server.services.signup.verifyEmailSignup(req.body.email, req.body.code); return { message: "Successfuly verified email", token, user }; } }); @@ -93,19 +90,14 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { if (!userAgent) throw new Error("user agent header is required"); const appCfg = getConfig(); - const { user, accessToken, refreshToken } = - await server.services.signup.completeEmailAccountSignup({ - ...req.body, - ip: req.realIp, - userAgent, - authorization: req.headers.authorization as string - }); + const { user, accessToken, refreshToken } = await server.services.signup.completeEmailAccountSignup({ + ...req.body, + ip: req.realIp, + userAgent, + authorization: req.headers.authorization as string + }); - void server.services.telemetry.sendLoopsEvent( - user.email, - user.firstName || "", - user.lastName || "" - ); + void server.services.telemetry.sendLoopsEvent(user.email, user.firstName || "", user.lastName || ""); void server.services.telemetry.sendPostHogEvents({ event: PostHogEventTypes.UserSignedUp, @@ -161,12 +153,11 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => { if (!userAgent) throw new Error("user agent header is required"); const appCfg = getConfig(); - const { user, accessToken, refreshToken } = - await server.services.signup.completeAccountInvite({ - ...req.body, - ip: req.realIp, - userAgent - }); + const { user, accessToken, refreshToken } = await server.services.signup.completeAccountInvite({ + ...req.body, + ip: req.realIp, + userAgent + }); await res.setCookie("jid", refreshToken, { httpOnly: true, diff --git a/backend/src/services/api-key/api-key-service.ts b/backend/src/services/api-key/api-key-service.ts index 23057e1a4..39ccbecce 100644 --- a/backend/src/services/api-key/api-key-service.ts +++ b/backend/src/services/api-key/api-key-service.ts @@ -45,8 +45,7 @@ export const apiKeyServiceFactory = ({ apiKeyDAL, userDAL }: TApiKeyServiceFacto const deleteApiKey = async (userId: string, apiKeyId: string) => { const [apiKeyData] = await apiKeyDAL.delete({ id: apiKeyId, userId }); - if (!apiKeyData) - throw new BadRequestError({ message: "Failed to find api key", name: "delete api key" }); + if (!apiKeyData) throw new BadRequestError({ message: "Failed to find api key", name: "delete api key" }); return formatApiKey(apiKeyData); }; diff --git a/backend/src/services/auth-token/auth-token-dal.ts b/backend/src/services/auth-token/auth-token-dal.ts index 87f2a653e..075ae7384 100644 --- a/backend/src/services/auth-token/auth-token-dal.ts +++ b/backend/src/services/auth-token/auth-token-dal.ts @@ -12,9 +12,7 @@ export type TTokenDALFactory = ReturnType; export const tokenDALFactory = (db: TDbClient) => { const authOrm = ormify(db, TableName.AuthTokens); - const findOneTokenSession = async ( - filter: Partial - ): Promise => { + const findOneTokenSession = async (filter: Partial): Promise => { try { const doc = await db(TableName.AuthTokenSession).where(filter).first(); return doc; @@ -29,20 +27,14 @@ export const tokenDALFactory = (db: TDbClient) => { orgId }: TDeleteTokenForUserDALDTO): Promise => { try { - const doc = await db(TableName.AuthTokens) - .where({ userId, type, orgId }) - .delete() - .returning("*"); + const doc = await db(TableName.AuthTokens).where({ userId, type, orgId }).delete().returning("*"); return doc; } catch (error) { throw new DatabaseError({ error, name: "DeleteTokenForUser" }); } }; - const decrementTriesField = async ({ - userId, - type - }: TDeleteTokenForUserDALDTO): Promise => { + const decrementTriesField = async ({ userId, type }: TDeleteTokenForUserDALDTO): Promise => { try { await db(TableName.AuthTokens).where({ userId, type }).decrement("triesLeft", 1); } catch (error) { @@ -99,10 +91,7 @@ export const tokenDALFactory = (db: TDbClient) => { const deleteTokenSession = async (filter: Partial, tx?: Knex) => { try { - const sessions = await (tx || db)(TableName.AuthTokenSession) - .where(filter) - .del() - .returning("*"); + const sessions = await (tx || db)(TableName.AuthTokenSession).where(filter).del().returning("*"); return sessions; } catch (error) { throw new DatabaseError({ name: "Delete token session", error }); diff --git a/backend/src/services/auth-token/auth-token-service.ts b/backend/src/services/auth-token/auth-token-service.ts index d19691209..7fae75c30 100644 --- a/backend/src/services/auth-token/auth-token-service.ts +++ b/backend/src/services/auth-token/auth-token-service.ts @@ -9,12 +9,7 @@ import { UnauthorizedError } from "@app/lib/errors"; import { AuthModeJwtTokenPayload } from "../auth/auth-type"; import { TUserDALFactory } from "../user/user-dal"; import { TTokenDALFactory } from "./auth-token-dal"; -import { - TCreateTokenForUserDTO, - TIssueAuthTokenDTO, - TokenType, - TValidateTokenForUserDTO -} from "./auth-token-types"; +import { TCreateTokenForUserDTO, TIssueAuthTokenDTO, TokenType, TValidateTokenForUserDTO } from "./auth-token-types"; type TAuthTokenServiceFactoryDep = { tokenDAL: TTokenDALFactory; @@ -125,14 +120,10 @@ export const tokenServiceFactory = ({ tokenDAL, userDAL }: TAuthTokenServiceFact return session; }; - const clearTokenSessionById = async ( - userId: string, - sessionId: string - ): Promise => + const clearTokenSessionById = async (userId: string, sessionId: string): Promise => tokenDAL.incrementTokenSessionVersion(userId, sessionId); - const getUserTokenSessionById = async (id: string, userId: string) => - tokenDAL.findOneTokenSession({ id, userId }); + const getUserTokenSessionById = async (id: string, userId: string) => tokenDAL.findOneTokenSession({ id, userId }); const getTokenSessionByUser = async (userId: string) => tokenDAL.findTokenSessions({ userId }); @@ -145,8 +136,7 @@ export const tokenServiceFactory = ({ tokenDAL, userDAL }: TAuthTokenServiceFact userId: token.userId }); if (!session) throw new UnauthorizedError({ name: "Session not found" }); - if (token.accessVersion !== session.accessVersion) - throw new UnauthorizedError({ name: "Stale session" }); + if (token.accessVersion !== session.accessVersion) throw new UnauthorizedError({ name: "Stale session" }); const user = await userDAL.findById(session.userId); if (!user || !user.isAccepted) throw new UnauthorizedError({ name: "Token user not found" }); diff --git a/backend/src/services/auth/auth-fns.ts b/backend/src/services/auth/auth-fns.ts index 91f34345c..3e65f7e05 100644 --- a/backend/src/services/auth/auth-fns.ts +++ b/backend/src/services/auth/auth-fns.ts @@ -3,19 +3,12 @@ import jwt from "jsonwebtoken"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, UnauthorizedError } from "@app/lib/errors"; -import { - AuthModeProviderJwtTokenPayload, - AuthModeProviderSignUpTokenPayload, - AuthTokenType -} from "./auth-type"; +import { AuthModeProviderJwtTokenPayload, AuthModeProviderSignUpTokenPayload, AuthTokenType } from "./auth-type"; export const validateProviderAuthToken = (providerToken: string, email: string) => { if (!providerToken) throw new UnauthorizedError(); const appCfg = getConfig(); - const decodedToken = jwt.verify( - providerToken, - appCfg.AUTH_SECRET - ) as AuthModeProviderJwtTokenPayload; + const decodedToken = jwt.verify(providerToken, appCfg.AUTH_SECRET) as AuthModeProviderJwtTokenPayload; if (decodedToken.authTokenType !== AuthTokenType.PROVIDER_TOKEN) throw new UnauthorizedError(); if (decodedToken.email !== email) throw new Error("Invalid auth credentials"); @@ -23,10 +16,7 @@ export const validateProviderAuthToken = (providerToken: string, email: string) export const validateSignUpAuthorization = (token: string, userId: string, validate = true) => { const appCfg = getConfig(); - const [AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE] = <[string, string]>token?.split(" ", 2) ?? [ - null, - null - ]; + const [AUTH_TOKEN_TYPE, AUTH_TOKEN_VALUE] = <[string, string]>token?.split(" ", 2) ?? [null, null]; if (AUTH_TOKEN_TYPE === null) { throw new BadRequestError({ message: "Missing Authorization Header in the request header." }); } @@ -41,10 +31,7 @@ export const validateSignUpAuthorization = (token: string, userId: string, valid }); } - const decodedToken = jwt.verify( - AUTH_TOKEN_VALUE, - appCfg.AUTH_SECRET - ) as AuthModeProviderSignUpTokenPayload; + const decodedToken = jwt.verify(AUTH_TOKEN_VALUE, appCfg.AUTH_SECRET) as AuthModeProviderSignUpTokenPayload; if (!validate) return decodedToken; if (decodedToken.authTokenType !== AuthTokenType.SIGNUP_TOKEN) throw new UnauthorizedError(); diff --git a/backend/src/services/auth/auth-login-service.ts b/backend/src/services/auth/auth-login-service.ts index e10fe6830..d63baeaca 100644 --- a/backend/src/services/auth/auth-login-service.ts +++ b/backend/src/services/auth/auth-login-service.ts @@ -25,11 +25,7 @@ type TAuthLoginServiceFactoryDep = { }; export type TAuthLoginFactory = ReturnType; -export const authLoginServiceFactory = ({ - userDAL, - tokenService, - smtpService -}: TAuthLoginServiceFactoryDep) => { +export const authLoginServiceFactory = ({ userDAL, tokenService, smtpService }: TAuthLoginServiceFactoryDep) => { /* * Private * Not exported. This is to update user device list @@ -37,9 +33,7 @@ export const authLoginServiceFactory = ({ */ const updateUserDeviceSession = async (user: TUsers, ip: string, userAgent: string) => { const devices = await UserDeviceSchema.parseAsync(user.devices || []); - const isDeviceSeen = devices.some( - (device) => device.ip === ip && device.userAgent === userAgent - ); + const isDeviceSeen = devices.some((device) => device.ip === ip && device.userAgent === userAgent); if (!isDeviceSeen) { const newDeviceList = devices.concat([{ ip, userAgent }]); @@ -159,8 +153,7 @@ export const authLoginServiceFactory = ({ validateProviderAuthToken(providerAuthToken as string, email); } - if (!userEnc.serverPrivateKey || !userEnc.clientPublicKey) - throw new Error("Failed to authenticate. Try again?"); + if (!userEnc.serverPrivateKey || !userEnc.clientPublicKey) throw new Error("Failed to authenticate. Try again?"); const isValidClientProof = await srpCheckClientProof( userEnc.salt, userEnc.verifier, @@ -176,11 +169,9 @@ export const authLoginServiceFactory = ({ }); // send multi factor auth token if they it enabled if (userEnc.isMfaEnabled) { - const mfaToken = jwt.sign( - { authTokenType: AuthTokenType.MFA_TOKEN, userId: userEnc.userId }, - cfg.AUTH_SECRET, - { expiresIn: cfg.JWT_MFA_LIFETIME } - ); + const mfaToken = jwt.sign({ authTokenType: AuthTokenType.MFA_TOKEN, userId: userEnc.userId }, cfg.AUTH_SECRET, { + expiresIn: cfg.JWT_MFA_LIFETIME + }); await sendUserMfaCode(userEnc.userId, userEnc.email); return { isMfaEnabled: true, token: mfaToken } as const; @@ -230,8 +221,7 @@ export const authLoginServiceFactory = ({ let user = await userDAL.findUserByEmail(email); const appCfg = getConfig(); const isOauthSignUpDisabled = !isSignupAllowed && !user; - if (isOauthSignUpDisabled) - throw new BadRequestError({ message: "User signup disabled", name: "Oauth 2 login" }); + if (isOauthSignUpDisabled) throw new BadRequestError({ message: "User signup disabled", name: "Oauth 2 login" }); if (!user) { user = await userDAL.create({ email, firstName, lastName, authMethods: [authMethod] }); diff --git a/backend/src/services/auth/auth-password-service.ts b/backend/src/services/auth/auth-password-service.ts index 3ea656184..ff07d422f 100644 --- a/backend/src/services/auth/auth-password-service.ts +++ b/backend/src/services/auth/auth-password-service.ts @@ -9,11 +9,7 @@ import { TokenType } from "../auth-token/auth-token-types"; import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service"; import { TUserDALFactory } from "../user/user-dal"; import { TAuthDALFactory } from "./auth-dal"; -import { - TChangePasswordDTO, - TCreateBackupPrivateKeyDTO, - TResetPasswordViaBackupKeyDTO -} from "./auth-password-type"; +import { TChangePasswordDTO, TCreateBackupPrivateKeyDTO, TResetPasswordViaBackupKeyDTO } from "./auth-password-type"; import { AuthTokenType } from "./auth-type"; type TAuthPasswordServiceFactoryDep = { @@ -70,8 +66,7 @@ export const authPaswordServiceFactory = ({ serverPrivateKey: null, clientPublicKey: null }); - if (!userEnc.serverPrivateKey || !userEnc.clientPublicKey) - throw new Error("Failed to authenticate. Try again?"); + if (!userEnc.serverPrivateKey || !userEnc.clientPublicKey) throw new Error("Failed to authenticate. Try again?"); const isValidClientProof = await srpCheckClientProof( userEnc.salt, userEnc.verifier, @@ -200,8 +195,7 @@ export const authPaswordServiceFactory = ({ throw new Error("Failed to find user"); } - if (!userEnc.clientPublicKey || !userEnc.serverPrivateKey) - throw new Error("failed to create backup key"); + if (!userEnc.clientPublicKey || !userEnc.serverPrivateKey) throw new Error("failed to create backup key"); const isValidClientProff = await srpCheckClientProof( userEnc.salt, userEnc.verifier, diff --git a/backend/src/services/auth/auth-signup-service.ts b/backend/src/services/auth/auth-signup-service.ts index 17e45845f..6090a2129 100644 --- a/backend/src/services/auth/auth-signup-service.ts +++ b/backend/src/services/auth/auth-signup-service.ts @@ -148,9 +148,7 @@ export const authSignupServiceFactory = ({ }); const hasSamlEnabled = user?.authMethods?.some((authMethod) => - [AuthMethod.OKTA_SAML, AuthMethod.AZURE_SAML, AuthMethod.JUMPCLOUD_SAML].includes( - authMethod as AuthMethod - ) + [AuthMethod.OKTA_SAML, AuthMethod.AZURE_SAML, AuthMethod.JUMPCLOUD_SAML].includes(authMethod as AuthMethod) ); if (!hasSamlEnabled) { @@ -162,9 +160,7 @@ export const authSignupServiceFactory = ({ { userId: user.id, status: OrgMembershipStatus.Accepted } ); const uniqueOrgId = [...new Set(updatedMembersips.map(({ orgId }) => orgId))]; - await Promise.allSettled( - uniqueOrgId.map((orgId) => licenseService.updateSubscriptionOrgMemberCount(orgId)) - ); + await Promise.allSettled(uniqueOrgId.map((orgId) => licenseService.updateSubscriptionOrgMemberCount(orgId))); const tokenSession = await tokenService.getUserTokenSession({ userAgent, @@ -259,9 +255,7 @@ export const authSignupServiceFactory = ({ tx ); const uniqueOrgId = [...new Set(updatedMembersips.map(({ orgId }) => orgId))]; - await Promise.allSettled( - uniqueOrgId.map((orgId) => licenseService.updateSubscriptionOrgMemberCount(orgId)) - ); + await Promise.allSettled(uniqueOrgId.map((orgId) => licenseService.updateSubscriptionOrgMemberCount(orgId))); return { info: us, key: userEncKey }; }); diff --git a/backend/src/services/identity-access-token/identity-access-token-dal.ts b/backend/src/services/identity-access-token/identity-access-token-dal.ts index edd4ef91e..42fb5bba5 100644 --- a/backend/src/services/identity-access-token/identity-access-token-dal.ts +++ b/backend/src/services/identity-access-token/identity-access-token-dal.ts @@ -14,11 +14,7 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => { try { const doc = await (tx || db)(TableName.IdentityAccessToken) .where(filter) - .join( - TableName.Identity, - `${TableName.Identity}.id`, - `${TableName.IdentityAccessToken}.identityId` - ) + .join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.IdentityAccessToken}.identityId`) .leftJoin( TableName.IdentityUaClientSecret, `${TableName.IdentityAccessToken}.identityUAClientSecretId`, diff --git a/backend/src/services/identity-access-token/identity-access-token-service.ts b/backend/src/services/identity-access-token/identity-access-token-service.ts index f5e3379af..cdc8effe2 100644 --- a/backend/src/services/identity-access-token/identity-access-token-service.ts +++ b/backend/src/services/identity-access-token/identity-access-token-service.ts @@ -7,18 +7,13 @@ import { checkIPAgainstBlocklist, TIp } from "@app/lib/ip"; import { AuthTokenType } from "../auth/auth-type"; import { TIdentityAccessTokenDALFactory } from "./identity-access-token-dal"; -import { - TIdentityAccessTokenJwtPayload, - TRenewAccessTokenDTO -} from "./identity-access-token-types"; +import { TIdentityAccessTokenJwtPayload, TRenewAccessTokenDTO } from "./identity-access-token-types"; type TIdentityAccessTokenServiceFactoryDep = { identityAccessTokenDAL: TIdentityAccessTokenDALFactory; }; -export type TIdentityAccessTokenServiceFactory = ReturnType< - typeof identityAccessTokenServiceFactory ->; +export type TIdentityAccessTokenServiceFactory = ReturnType; export const identityAccessTokenServiceFactory = ({ identityAccessTokenDAL @@ -33,11 +28,7 @@ export const identityAccessTokenServiceFactory = ({ createdAt: accessTokenCreatedAt } = identityAccessToken; - if ( - accessTokenNumUsesLimit > 0 && - accessTokenNumUses > 0 && - accessTokenNumUses >= accessTokenNumUsesLimit - ) { + if (accessTokenNumUsesLimit > 0 && accessTokenNumUses > 0 && accessTokenNumUses >= accessTokenNumUsesLimit) { throw new BadRequestError({ message: "Unable to renew because access token number of uses limit reached" }); @@ -95,8 +86,7 @@ export const identityAccessTokenServiceFactory = ({ const decodedToken = jwt.verify(accessToken, appCfg.AUTH_SECRET) as JwtPayload & { identityAccessTokenId: string; }; - if (decodedToken.authTokenType !== AuthTokenType.IDENTITY_ACCESS_TOKEN) - throw new UnauthorizedError(); + if (decodedToken.authTokenType !== AuthTokenType.IDENTITY_ACCESS_TOKEN) throw new UnauthorizedError(); const identityAccessToken = await identityAccessTokenDAL.findOne({ [`${TableName.IdentityAccessToken}.id` as "id"]: decodedToken.identityAccessTokenId, @@ -106,20 +96,14 @@ export const identityAccessTokenServiceFactory = ({ validateAccessTokenExp(identityAccessToken); - const updatedIdentityAccessToken = await identityAccessTokenDAL.updateById( - identityAccessToken.id, - { - accessTokenLastRenewedAt: new Date() - } - ); + const updatedIdentityAccessToken = await identityAccessTokenDAL.updateById(identityAccessToken.id, { + accessTokenLastRenewedAt: new Date() + }); return { accessToken, identityAccessToken: updatedIdentityAccessToken }; }; - const fnValidateIdentityAccessToken = async ( - token: TIdentityAccessTokenJwtPayload, - ipAddress?: string - ) => { + const fnValidateIdentityAccessToken = async (token: TIdentityAccessTokenJwtPayload, ipAddress?: string) => { const identityAccessToken = await identityAccessTokenDAL.findOne({ [`${TableName.IdentityAccessToken}.id` as "id"]: token.identityAccessTokenId, isAccessTokenRevoked: false diff --git a/backend/src/services/identity-project/identity-project-dal.ts b/backend/src/services/identity-project/identity-project-dal.ts index fd906cf10..dbb864387 100644 --- a/backend/src/services/identity-project/identity-project-dal.ts +++ b/backend/src/services/identity-project/identity-project-dal.ts @@ -14,11 +14,7 @@ export const identityProjectDALFactory = (db: TDbClient) => { try { const docs = await (tx || db)(TableName.IdentityProjectMembership) .where(`${TableName.IdentityProjectMembership}.projectId`, projectId) - .join( - TableName.Identity, - `${TableName.IdentityProjectMembership}.identityId`, - `${TableName.Identity}.id` - ) + .join(TableName.Identity, `${TableName.IdentityProjectMembership}.identityId`, `${TableName.Identity}.id`) .leftJoin( TableName.ProjectRoles, `${TableName.IdentityProjectMembership}.roleId`, diff --git a/backend/src/services/identity-project/identity-project-service.ts b/backend/src/services/identity-project/identity-project-service.ts index d8c42dde6..05e0bd68b 100644 --- a/backend/src/services/identity-project/identity-project-service.ts +++ b/backend/src/services/identity-project/identity-project-service.ts @@ -2,10 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { ProjectMembershipRole, TProjectRoles } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { BadRequestError, ForbiddenRequestError } from "@app/lib/errors"; @@ -24,10 +21,7 @@ type TIdentityProjectServiceFactoryDep = { identityProjectDAL: TIdentityProjectDALFactory; projectDAL: Pick; identityOrgMembershipDAL: Pick; - permissionService: Pick< - TPermissionServiceFactory, - "getProjectPermission" | "getProjectPermissionByRole" - >; + permissionService: Pick; }; export type TIdentityProjectServiceFactory = ReturnType; @@ -38,18 +32,9 @@ export const identityProjectServiceFactory = ({ identityOrgMembershipDAL, projectDAL }: TIdentityProjectServiceFactoryDep) => { - const createProjectIdentity = async ({ - identityId, - actor, - actorId, - projectId, - role - }: TCreateProjectIdentityDTO) => { + const createProjectIdentity = async ({ identityId, actor, actorId, projectId, role }: TCreateProjectIdentityDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Identity - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Identity); const existingIdentity = await identityProjectDAL.findOne({ identityId, projectId }); if (existingIdentity) @@ -67,8 +52,10 @@ export const identityProjectServiceFactory = ({ message: `Failed to find identity with id ${identityId}` }); - const { permission: rolePermission, role: customRole } = - await permissionService.getProjectPermissionByRole(role, project.id); + const { permission: rolePermission, role: customRole } = await permissionService.getProjectPermissionByRole( + role, + project.id + ); const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission); if (!hasPriviledge) throw new ForbiddenRequestError({ @@ -85,18 +72,9 @@ export const identityProjectServiceFactory = ({ return projectIdentity; }; - const updateProjectIdentity = async ({ - projectId, - identityId, - role, - actor, - actorId - }: TUpdateProjectIdentityDTO) => { + const updateProjectIdentity = async ({ projectId, identityId, role, actor, actorId }: TUpdateProjectIdentityDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Identity - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity); const projectIdentity = await identityProjectDAL.findOne({ identityId, projectId }); if (!projectIdentity) @@ -115,8 +93,10 @@ export const identityProjectServiceFactory = ({ let customRole: TProjectRoles | undefined; if (role) { - const { permission: rolePermission, role: customOrgRole } = - await permissionService.getProjectPermissionByRole(role, projectIdentity.projectId); + const { permission: rolePermission, role: customOrgRole } = await permissionService.getProjectPermissionByRole( + role, + projectIdentity.projectId + ); const isCustomRole = Boolean(customOrgRole); const hasRequiredNewRolePermission = isAtLeastAsPrivileged(permission, rolePermission); @@ -135,12 +115,7 @@ export const identityProjectServiceFactory = ({ return updatedProjectIdentity; }; - const deleteProjectIdentity = async ({ - identityId, - actorId, - actor, - projectId - }: TDeleteProjectIdentityDTO) => { + const deleteProjectIdentity = async ({ identityId, actorId, actor, projectId }: TDeleteProjectIdentityDTO) => { const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId }); if (!identityProjectMembership) throw new BadRequestError({ message: `Failed to find identity with id ${identityId}` }); @@ -150,10 +125,7 @@ export const identityProjectServiceFactory = ({ actorId, identityProjectMembership.projectId ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Identity - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Identity); const { permission: identityRolePermission } = await permissionService.getProjectPermission( ActorType.IDENTITY, identityId, @@ -169,10 +141,7 @@ export const identityProjectServiceFactory = ({ const listProjectIdentities = async ({ projectId, actor, actorId }: TListProjectIdentityDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Identity - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Identity); const identityMemberhips = await identityProjectDAL.findByProjectId(projectId); return identityMemberhips; diff --git a/backend/src/services/identity-ua/identity-ua-service.ts b/backend/src/services/identity-ua/identity-ua-service.ts index 1eb528977..aa5c3c895 100644 --- a/backend/src/services/identity-ua/identity-ua-service.ts +++ b/backend/src/services/identity-ua/identity-ua-service.ts @@ -6,10 +6,7 @@ import jwt from "jsonwebtoken"; import { IdentityAuthMethod } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { - OrgPermissionActions, - OrgPermissionSubjects -} from "@app/ee/services/permission/org-permission"; +import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { getConfig } from "@app/lib/config/env"; @@ -71,8 +68,7 @@ export const identityUaServiceFactory = ({ ); if (!validClientSecretInfo) throw new UnauthorizedError(); - const { clientSecretTTL, clientSecretNumUses, clientSecretNumUsesLimit } = - validClientSecretInfo; + const { clientSecretTTL, clientSecretNumUses, clientSecretNumUsesLimit } = validClientSecretInfo; if (clientSecretTTL > 0) { const clientSecretCreated = new Date(validClientSecretInfo.createdAt); const ttlInMilliseconds = clientSecretTTL * 1000; @@ -97,16 +93,12 @@ export const identityUaServiceFactory = ({ isClientSecretRevoked: true }); throw new UnauthorizedError({ - message: - "Failed to authenticate identity credentials due to client secret number of uses limit reached" + message: "Failed to authenticate identity credentials due to client secret number of uses limit reached" }); } const identityAccessToken = await identityUaDAL.transaction(async (tx) => { - const uaClientSecretDoc = await identityUaClientSecretDAL.incrementUsage( - validClientSecretInfo.id, - tx - ); + const uaClientSecretDoc = await identityUaClientSecretDAL.incrementUsage(validClientSecretInfo.id, tx); const newToken = await identityAccessTokenDAL.create( { identityId: identityUa.identityId, @@ -132,10 +124,7 @@ export const identityUaServiceFactory = ({ } as TIdentityAccessTokenJwtPayload, appCfg.AUTH_SECRET, { - expiresIn: - identityAccessToken.accessTokenMaxTTL === 0 - ? undefined - : identityAccessToken.accessTokenMaxTTL + expiresIn: identityAccessToken.accessTokenMaxTTL === 0 ? undefined : identityAccessToken.accessTokenMaxTTL } ); return { accessToken, identityUa, validClientSecretInfo, identityAccessToken }; @@ -162,35 +151,26 @@ export const identityUaServiceFactory = ({ throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" }); } - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - identityMembershipOrg.orgId - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.Identity - ); + const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity); const plan = await licenseService.getPlan(identityMembershipOrg.orgId); - const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map( - (clientSecretTrustedIp) => { - if ( - !plan.ipAllowlisting && - clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" && - clientSecretTrustedIp.ipAddress !== "::/0" - ) - throw new BadRequestError({ - message: - "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range." - }); - if (!isValidIpOrCidr(clientSecretTrustedIp.ipAddress)) - throw new BadRequestError({ - message: "The IP is not a valid IPv4, IPv6, or CIDR block" - }); - return extractIPDetails(clientSecretTrustedIp.ipAddress); - } - ); + const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => { + if ( + !plan.ipAllowlisting && + clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" && + clientSecretTrustedIp.ipAddress !== "::/0" + ) + throw new BadRequestError({ + message: + "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range." + }); + if (!isValidIpOrCidr(clientSecretTrustedIp.ipAddress)) + throw new BadRequestError({ + message: "The IP is not a valid IPv4, IPv6, or CIDR block" + }); + return extractIPDetails(clientSecretTrustedIp.ipAddress); + }); const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { if ( !plan.ipAllowlisting && @@ -254,41 +234,31 @@ export const identityUaServiceFactory = ({ if ( (accessTokenMaxTTL || uaIdentityAuth.accessTokenMaxTTL) > 0 && - (accessTokenTTL || uaIdentityAuth.accessTokenMaxTTL) > - (accessTokenMaxTTL || uaIdentityAuth.accessTokenMaxTTL) + (accessTokenTTL || uaIdentityAuth.accessTokenMaxTTL) > (accessTokenMaxTTL || uaIdentityAuth.accessTokenMaxTTL) ) { throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" }); } - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - identityMembershipOrg.orgId - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Edit, - OrgPermissionSubjects.Identity - ); + const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity); const plan = await licenseService.getPlan(identityMembershipOrg.orgId); - const reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map( - (clientSecretTrustedIp) => { - if ( - !plan.ipAllowlisting && - clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" && - clientSecretTrustedIp.ipAddress !== "::/0" - ) - throw new BadRequestError({ - message: - "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range." - }); - if (!isValidIpOrCidr(clientSecretTrustedIp.ipAddress)) - throw new BadRequestError({ - message: "The IP is not a valid IPv4, IPv6, or CIDR block" - }); - return extractIPDetails(clientSecretTrustedIp.ipAddress); - } - ); + const reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map((clientSecretTrustedIp) => { + if ( + !plan.ipAllowlisting && + clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" && + clientSecretTrustedIp.ipAddress !== "::/0" + ) + throw new BadRequestError({ + message: + "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range." + }); + if (!isValidIpOrCidr(clientSecretTrustedIp.ipAddress)) + throw new BadRequestError({ + message: "The IP is not a valid IPv4, IPv6, or CIDR block" + }); + return extractIPDetails(clientSecretTrustedIp.ipAddress); + }); const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { if ( !plan.ipAllowlisting && @@ -330,15 +300,8 @@ export const identityUaServiceFactory = ({ const uaIdentityAuth = await identityUaDAL.findOne({ identityId }); - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - identityMembershipOrg.orgId - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Identity - ); + const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity); return { ...uaIdentityAuth, orgId: identityMembershipOrg.orgId }; }; @@ -356,15 +319,8 @@ export const identityUaServiceFactory = ({ throw new BadRequestError({ message: "The identity does not have universal auth" }); - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - identityMembershipOrg.orgId - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.Identity - ); + const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity); const { permission: rolePermission } = await permissionService.getOrgPermission( ActorType.IDENTITY, @@ -409,15 +365,8 @@ export const identityUaServiceFactory = ({ throw new BadRequestError({ message: "The identity does not have universal auth" }); - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - identityMembershipOrg.orgId - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Identity - ); + const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity); const { permission: rolePermission } = await permissionService.getOrgPermission( ActorType.IDENTITY, @@ -441,27 +390,15 @@ export const identityUaServiceFactory = ({ return { clientSecrets, orgId: identityMembershipOrg.orgId }; }; - const revokeUaClientSecret = async ({ - identityId, - actorId, - actor, - clientSecretId - }: TRevokeUaClientSecretDTO) => { + const revokeUaClientSecret = async ({ identityId, actorId, actor, clientSecretId }: TRevokeUaClientSecretDTO) => { const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" }); if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral) throw new BadRequestError({ message: "The identity does not have universal auth" }); - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - identityMembershipOrg.orgId - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Delete, - OrgPermissionSubjects.Identity - ); + const { permission } = await permissionService.getOrgPermission(actor, actorId, identityMembershipOrg.orgId); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity); const { permission: rolePermission } = await permissionService.getOrgPermission( ActorType.IDENTITY, diff --git a/backend/src/services/identity/identity-org-dal.ts b/backend/src/services/identity/identity-org-dal.ts index c5413d058..95d742f33 100644 --- a/backend/src/services/identity/identity-org-dal.ts +++ b/backend/src/services/identity/identity-org-dal.ts @@ -14,11 +14,7 @@ export const identityOrgDALFactory = (db: TDbClient) => { try { const [data] = await (tx || db)(TableName.IdentityOrgMembership) .where(filter) - .join( - TableName.Identity, - `${TableName.IdentityOrgMembership}.identityId`, - `${TableName.Identity}.id` - ) + .join(TableName.Identity, `${TableName.IdentityOrgMembership}.identityId`, `${TableName.Identity}.id`) .select(selectAllTableCols(TableName.IdentityOrgMembership)) .select(db.ref("name").withSchema(TableName.Identity)) .select(db.ref("authMethod").withSchema(TableName.Identity)); @@ -35,16 +31,8 @@ export const identityOrgDALFactory = (db: TDbClient) => { try { const docs = await (tx || db)(TableName.IdentityOrgMembership) .where(`${TableName.IdentityOrgMembership}.orgId`, orgId) - .join( - TableName.Identity, - `${TableName.IdentityOrgMembership}.identityId`, - `${TableName.Identity}.id` - ) - .leftJoin( - TableName.OrgRoles, - `${TableName.IdentityOrgMembership}.roleId`, - `${TableName.OrgRoles}.id` - ) + .join(TableName.Identity, `${TableName.IdentityOrgMembership}.identityId`, `${TableName.Identity}.id`) + .leftJoin(TableName.OrgRoles, `${TableName.IdentityOrgMembership}.roleId`, `${TableName.OrgRoles}.id`) .select(selectAllTableCols(TableName.IdentityOrgMembership)) // cr stands for custom role .select(db.ref("id").as("crId").withSchema(TableName.OrgRoles)) diff --git a/backend/src/services/identity/identity-service.ts b/backend/src/services/identity/identity-service.ts index bc87b1f06..3dd494034 100644 --- a/backend/src/services/identity/identity-service.ts +++ b/backend/src/services/identity/identity-service.ts @@ -1,10 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { OrgMembershipRole, TOrgRoles } from "@app/db/schemas"; -import { - OrgPermissionActions, - OrgPermissionSubjects -} from "@app/ee/services/permission/org-permission"; +import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { BadRequestError, ForbiddenRequestError } from "@app/lib/errors"; @@ -30,17 +27,15 @@ export const identityServiceFactory = ({ }: TIdentityServiceFactoryDep) => { const createIdentity = async ({ name, role, actor, orgId, actorId }: TCreateIdentityDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.Identity - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity); - const { permission: rolePermission, role: customRole } = - await permissionService.getOrgPermissionByRole(role, orgId); + const { permission: rolePermission, role: customRole } = await permissionService.getOrgPermissionByRole( + role, + orgId + ); const isCustomRole = Boolean(customRole); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, rolePermission); - if (!hasRequiredPriviledges) - throw new BadRequestError({ message: "Failed to create a more privileged identity" }); + if (!hasRequiredPriviledges) throw new BadRequestError({ message: "Failed to create a more privileged identity" }); const identity = await identityDAL.transaction(async (tx) => { const newIdentity = await identityDAL.create({ name }, tx); @@ -61,18 +56,10 @@ export const identityServiceFactory = ({ const updateIdentity = async ({ id, role, name, actor, actorId }: TUpdateIdentityDTO) => { const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id }); - if (!identityOrgMembership) - throw new BadRequestError({ message: `Failed to find identity with id ${id}` }); + if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` }); - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - identityOrgMembership.orgId - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Edit, - OrgPermissionSubjects.Identity - ); + const { permission } = await permissionService.getOrgPermission(actor, actorId, identityOrgMembership.orgId); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity); const { permission: identityRolePermission } = await permissionService.getOrgPermission( ActorType.IDENTITY, @@ -85,8 +72,10 @@ export const identityServiceFactory = ({ let customRole: TOrgRoles | undefined; if (role) { - const { permission: rolePermission, role: customOrgRole } = - await permissionService.getOrgPermissionByRole(role, identityOrgMembership.orgId); + const { permission: rolePermission, role: customOrgRole } = await permissionService.getOrgPermissionByRole( + role, + identityOrgMembership.orgId + ); const isCustomRole = Boolean(customOrgRole); const hasRequiredNewRolePermission = isAtLeastAsPrivileged(permission, rolePermission); @@ -96,9 +85,7 @@ export const identityServiceFactory = ({ } const identity = await identityDAL.transaction(async (tx) => { - const newIdentity = name - ? await identityDAL.updateById(id, { name }, tx) - : await identityDAL.findById(id, tx); + const newIdentity = name ? await identityDAL.updateById(id, { name }, tx) : await identityDAL.findById(id, tx); if (role) { await identityOrgMembershipDAL.update( { identityId: id }, @@ -117,18 +104,10 @@ export const identityServiceFactory = ({ const deleteIdentity = async ({ actorId, actor, id }: TDeleteIdentityDTO) => { const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id }); - if (!identityOrgMembership) - throw new BadRequestError({ message: `Failed to find identity with id ${id}` }); + if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` }); - const { permission } = await permissionService.getOrgPermission( - actor, - actorId, - identityOrgMembership.orgId - ); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Delete, - OrgPermissionSubjects.Identity - ); + const { permission } = await permissionService.getOrgPermission(actor, actorId, identityOrgMembership.orgId); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity); const { permission: identityRolePermission } = await permissionService.getOrgPermission( ActorType.IDENTITY, id, @@ -144,10 +123,7 @@ export const identityServiceFactory = ({ const listOrgIdentities = async ({ orgId, actor, actorId }: TOrgPermission) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Identity - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity); const identityMemberhips = await identityOrgMembershipDAL.findByOrgId(orgId); return identityMemberhips; diff --git a/backend/src/services/integration-auth/integration-app-list.ts b/backend/src/services/integration-auth/integration-app-list.ts index cd72fc60b..17b1b63ad 100644 --- a/backend/src/services/integration-auth/integration-app-list.ts +++ b/backend/src/services/integration-auth/integration-app-list.ts @@ -22,11 +22,7 @@ const getAppsGCPSecretManager = async ({ accessToken }: { accessToken: string }) interface GCPApp { projectNumber: string; projectId: string; - lifecycleState: - | "ACTIVE" - | "LIFECYCLE_STATE_UNSPECIFIED" - | "DELETE_REQUESTED" - | "DELETE_IN_PROGRESS"; + lifecycleState: "ACTIVE" | "LIFECYCLE_STATE_UNSPECIFIED" | "DELETE_REQUESTED" | "DELETE_IN_PROGRESS"; name: string; createTime: string; parent: { @@ -131,30 +127,21 @@ const getAppsHeroku = async ({ accessToken }: { accessToken: string }) => { /** * Return list of names of apps for Vercel integration */ -const getAppsVercel = async ({ - accessToken, - teamId -}: { - teamId?: string | null; - accessToken: string; -}) => { +const getAppsVercel = async ({ accessToken, teamId }: { teamId?: string | null; accessToken: string }) => { const res = ( - await request.get<{ projects: { name: string; id: string }[] }>( - `${IntegrationUrls.VERCEL_API_URL}/v9/projects`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - }, - ...(teamId - ? { - params: { - teamId - } + await request.get<{ projects: { name: string; id: string }[] }>(`${IntegrationUrls.VERCEL_API_URL}/v9/projects`, { + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" + }, + ...(teamId + ? { + params: { + teamId } - : {}) - } - ) + } + : {}) + }) ).data; const apps = res.projects.map((a) => ({ @@ -273,16 +260,13 @@ const getAppsGithub = async ({ accessToken }: { accessToken: string }) => { */ const getAppsRender = async ({ accessToken }: { accessToken: string }) => { const res = ( - await request.get<{ service: { name: string; id: string } }[]>( - `${IntegrationUrls.RENDER_API_URL}/v1/services`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - Accept: "application/json", - "Accept-Encoding": "application/json" - } + await request.get<{ service: { name: string; id: string } }[]>(`${IntegrationUrls.RENDER_API_URL}/v1/services`, { + headers: { + Authorization: `Bearer ${accessToken}`, + Accept: "application/json", + "Accept-Encoding": "application/json" } - ) + }) ).data; const apps = res.map((a) => ({ @@ -346,13 +330,7 @@ const getAppsRailway = async ({ accessToken }: { accessToken: string }) => { /** * Return list of sites for Laravel Forge integration */ -const getAppsLaravelForge = async ({ - accessToken, - serverId -}: { - accessToken: string; - serverId?: string; -}) => { +const getAppsLaravelForge = async ({ accessToken, serverId }: { accessToken: string; serverId?: string }) => { const res = ( await request.get<{ sites: { name: string; id: string }[] }>( `${IntegrationUrls.LARAVELFORGE_API_URL}/api/v1/servers/${serverId}/sites`, @@ -464,13 +442,7 @@ const getAppsTravisCI = async ({ accessToken }: { accessToken: string }) => { /** * Return list of projects for Terraform Cloud integration */ -const getAppsTerraformCloud = async ({ - accessToken, - workspacesId -}: { - accessToken: string; - workspacesId?: string; -}) => { +const getAppsTerraformCloud = async ({ accessToken, workspacesId }: { accessToken: string; workspacesId?: string }) => { const res = ( await request.get<{ data: { attributes: { name: string }; id: string } }>( `${IntegrationUrls.TERRAFORM_CLOUD_API_URL}/api/v2/workspaces/${workspacesId}`, @@ -566,16 +538,13 @@ const getAppsGitlab = async ({ per_page: String(perPage) }); - const { data } = await request.get<{ name: string; id: string }[]>( - `${gitLabApiUrl}/v4/users/${id}/projects`, - { - params, - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } + const { data } = await request.get<{ name: string; id: string }[]>(`${gitLabApiUrl}/v4/users/${id}/projects`, { + params, + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" } - ); + }); data.forEach((a) => { apps.push({ @@ -642,15 +611,12 @@ const getAppsSupabase = async ({ accessToken }: { accessToken: string }) => { * Return list of accounts for the Checkly integration */ const getAppsCheckly = async ({ accessToken }: { accessToken: string }) => { - const { data } = await request.get<{ name: string; id: string }[]>( - `${IntegrationUrls.CHECKLY_API_URL}/v1/accounts`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - Accept: "application/json" - } + const { data } = await request.get<{ name: string; id: string }[]>(`${IntegrationUrls.CHECKLY_API_URL}/v1/accounts`, { + headers: { + Authorization: `Bearer ${accessToken}`, + Accept: "application/json" } - ); + }); const apps = data.map((a) => ({ name: a.name, @@ -663,13 +629,7 @@ const getAppsCheckly = async ({ accessToken }: { accessToken: string }) => { /** * Return list of projects for the Cloudflare Pages integration */ -const getAppsCloudflarePages = async ({ - accessToken, - accountId -}: { - accessToken: string; - accountId?: string; -}) => { +const getAppsCloudflarePages = async ({ accessToken, accountId }: { accessToken: string; accountId?: string }) => { const { data } = await request.get<{ result: { name: string; id: string }[] }>( `${IntegrationUrls.CLOUDFLARE_PAGES_API_URL}/client/v4/accounts/${accountId}/pages/projects`, { @@ -690,13 +650,7 @@ const getAppsCloudflarePages = async ({ /** * Return list of projects for the Cloudflare Workers integration */ -const getAppsCloudflareWorkers = async ({ - accessToken, - accountId -}: { - accessToken: string; - accountId?: string; -}) => { +const getAppsCloudflareWorkers = async ({ accessToken, accountId }: { accessToken: string; accountId?: string }) => { const { data } = await request.get<{ result: { id: string }[] }>( `${IntegrationUrls.CLOUDFLARE_WORKERS_API_URL}/client/v4/accounts/${accountId}/workers/services`, { @@ -717,13 +671,7 @@ const getAppsCloudflareWorkers = async ({ /** * Return list of repositories for the BitBucket integration based on provided BitBucket workspace */ -const getAppsBitBucket = async ({ - accessToken, - workspaceSlug -}: { - accessToken: string; - workspaceSlug?: string; -}) => { +const getAppsBitBucket = async ({ accessToken, workspaceSlug }: { accessToken: string; workspaceSlug?: string }) => { interface RepositoriesResponse { size: number; page: number; @@ -881,25 +829,19 @@ const getAppsWindmill = async ({ accessToken }: { accessToken: string }) => { // is write access is allowed then delete the created secrets from workspace if (writeUser && writeFolder) { - await request.delete( - `${IntegrationUrls.WINDMILL_API_URL}/w/${app.id}/variables/delete/${userPath}`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } + await request.delete(`${IntegrationUrls.WINDMILL_API_URL}/w/${app.id}/variables/delete/${userPath}`, { + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" } - ); + }); - await request.delete( - `${IntegrationUrls.WINDMILL_API_URL}/w/${app.id}/variables/delete/${folderPath}`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } + await request.delete(`${IntegrationUrls.WINDMILL_API_URL}/w/${app.id}/variables/delete/${folderPath}`, { + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" } - ); + }); return app; } @@ -910,9 +852,7 @@ const getAppsWindmill = async ({ accessToken }: { accessToken: string }) => { }); const appsWriteResponses = await Promise.all(writeAccessCheck); - const appsWithWriteAccess = appsWriteResponses.filter( - (appRes) => !(appRes as { error: string })?.error - ); + const appsWithWriteAccess = appsWriteResponses.filter((appRes) => !(appRes as { error: string })?.error); const apps = (appsWithWriteAccess as { id: string; name: string }[]).map((a) => ({ name: a.name, @@ -945,15 +885,12 @@ const getAppsDigitalOceanAppPlatform = async ({ accessToken }: { accessToken: st } const res = ( - await request.get<{ apps: DigitalOceanApp[] }>( - `${IntegrationUrls.DIGITAL_OCEAN_API_URL}/v2/apps`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } + await request.get<{ apps: DigitalOceanApp[] }>(`${IntegrationUrls.DIGITAL_OCEAN_API_URL}/v2/apps`, { + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" } - ) + }) ).data; return (res.apps ?? []).map((a) => ({ diff --git a/backend/src/services/integration-auth/integration-auth-service.ts b/backend/src/services/integration-auth/integration-auth-service.ts index 519ae0230..844e01f3c 100644 --- a/backend/src/services/integration-auth/integration-auth-service.ts +++ b/backend/src/services/integration-auth/integration-auth-service.ts @@ -1,21 +1,10 @@ import { ForbiddenError } from "@casl/ability"; -import { - SecretEncryptionAlgo, - SecretKeyEncoding, - TIntegrationAuths, - TIntegrationAuthsInsert -} from "@app/db/schemas"; +import { SecretEncryptionAlgo, SecretKeyEncoding, TIntegrationAuths, TIntegrationAuthsInsert } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { request } from "@app/lib/config/request"; -import { - decryptSymmetric128BitHexKeyUTF8, - encryptSymmetric128BitHexKeyUTF8 -} from "@app/lib/crypto"; +import { decryptSymmetric128BitHexKeyUTF8, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto"; import { BadRequestError } from "@app/lib/errors"; import { TProjectPermission } from "@app/lib/types"; @@ -70,16 +59,9 @@ export const integrationAuthServiceFactory = ({ projectBotDAL, projectBotService }: TIntegrationAuthServiceFactoryDep) => { - const listIntegrationAuthByProjectId = async ({ - actorId, - actor, - projectId - }: TProjectPermission) => { + const listIntegrationAuthByProjectId = async ({ actorId, actor, projectId }: TProjectPermission) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const authorizations = await integrationAuthDAL.find({ projectId }); return authorizations; }; @@ -88,38 +70,20 @@ export const integrationAuthServiceFactory = ({ const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); return integrationAuth; }; - const oauthExchange = async ({ - projectId, - actorId, - actor, - integration, - url, - code - }: TOauthExchangeDTO) => { + const oauthExchange = async ({ projectId, actorId, actor, integration, url, code }: TOauthExchangeDTO) => { if (!Object.values(Integrations).includes(integration as Integrations)) throw new BadRequestError({ message: "Invalid integration" }); const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Integrations - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); const bot = await projectBotDAL.findOne({ isActive: true, projectId }); - if (!bot) - throw new BadRequestError({ message: "Bot must be enabled for oauth2 code token exchange" }); + if (!bot) throw new BadRequestError({ message: "Bot must be enabled for oauth2 code token exchange" }); const tokenExchange = await exchangeCode({ integration, code, url }); const updateDoc: TIntegrationAuthsInsert = { @@ -178,14 +142,10 @@ export const integrationAuthServiceFactory = ({ throw new BadRequestError({ message: "Invalid integration" }); const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Integrations - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); const bot = await projectBotDAL.findOne({ isActive: true, projectId }); - if (!bot) - throw new BadRequestError({ message: "Bot must be enabled for oauth2 code token exchange" }); + if (!bot) throw new BadRequestError({ message: "Bot must be enabled for oauth2 code token exchange" }); const updateDoc: TIntegrationAuthsInsert = { projectId, @@ -251,11 +211,7 @@ export const integrationAuthServiceFactory = ({ }); } - if ( - integrationAuth.refreshCiphertext && - integrationAuth.refreshIV && - integrationAuth.refreshTag - ) { + if (integrationAuth.refreshCiphertext && integrationAuth.refreshIV && integrationAuth.refreshTag) { const refreshToken = decryptSymmetric128BitHexKeyUTF8({ key: botKey, ciphertext: integrationAuth.refreshCiphertext, @@ -287,11 +243,7 @@ export const integrationAuthServiceFactory = ({ } if (!accessToken) throw new BadRequestError({ message: "Missing access token" }); - if ( - integrationAuth.accessIdTag && - integrationAuth.accessIdIV && - integrationAuth.accessIdCiphertext - ) { + if (integrationAuth.accessIdTag && integrationAuth.accessIdIV && integrationAuth.accessIdCiphertext) { accessId = decryptSymmetric128BitHexKeyUTF8({ key: botKey, ciphertext: integrationAuth.accessIdCiphertext, @@ -302,25 +254,12 @@ export const integrationAuthServiceFactory = ({ return { accessId, accessToken }; }; - const getIntegrationApps = async ({ - actor, - actorId, - teamId, - id, - workspaceSlug - }: TIntegrationAuthAppsDTO) => { + const getIntegrationApps = async ({ actor, actorId, teamId, id, workspaceSlug }: TIntegrationAuthAppsDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken, accessId } = await getIntegrationAccessToken(integrationAuth, botKey); @@ -339,15 +278,8 @@ export const integrationAuthServiceFactory = ({ const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); @@ -359,24 +291,12 @@ export const integrationAuthServiceFactory = ({ return teams; }; - const getVercelBranches = async ({ - appId, - id, - actor, - actorId - }: TIntegrationAuthVercelBranchesDTO) => { + const getVercelBranches = async ({ appId, id, actor, actorId }: TIntegrationAuthVercelBranchesDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); @@ -399,37 +319,22 @@ export const integrationAuthServiceFactory = ({ return []; }; - const getChecklyGroups = async ({ - actorId, - actor, - id, - accountId - }: TIntegrationAuthChecklyGroupsDTO) => { + const getChecklyGroups = async ({ actorId, actor, id, accountId }: TIntegrationAuthChecklyGroupsDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); if (accountId) { - const { data } = await request.get( - `${IntegrationUrls.CHECKLY_API_URL}/v1/check-groups`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - Accept: "application/json", - "X-Checkly-Account": accountId - } + const { data } = await request.get(`${IntegrationUrls.CHECKLY_API_URL}/v1/check-groups`, { + headers: { + Authorization: `Bearer ${accessToken}`, + Accept: "application/json", + "X-Checkly-Account": accountId } - ); + }); return data.map(({ name, id: groupId }) => ({ name, groupId })); } return []; @@ -439,15 +344,8 @@ export const integrationAuthServiceFactory = ({ const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); const { data } = await request.get<{ results: Array<{ id: string; name: string }> }>( @@ -463,24 +361,12 @@ export const integrationAuthServiceFactory = ({ return data.results.map(({ name, id: orgId }) => ({ name, orgId })); }; - const getQoveryProjects = async ({ - actorId, - actor, - id, - orgId - }: TIntegrationAuthQoveryProjectDTO) => { + const getQoveryProjects = async ({ actorId, actor, id, orgId }: TIntegrationAuthQoveryProjectDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); if (orgId) { @@ -498,24 +384,12 @@ export const integrationAuthServiceFactory = ({ return []; }; - const getQoveryEnvs = async ({ - projectId, - id, - actor, - actorId - }: TIntegrationAuthQoveryEnvironmentsDTO) => { + const getQoveryEnvs = async ({ projectId, id, actor, actorId }: TIntegrationAuthQoveryEnvironmentsDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); if (projectId && projectId !== "none") { @@ -538,24 +412,12 @@ export const integrationAuthServiceFactory = ({ return []; }; - const getQoveryApps = async ({ - id, - actor, - actorId, - environmentId - }: TIntegrationAuthQoveryScopesDTO) => { + const getQoveryApps = async ({ id, actor, actorId, environmentId }: TIntegrationAuthQoveryScopesDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); if (environmentId) { @@ -577,24 +439,12 @@ export const integrationAuthServiceFactory = ({ return []; }; - const getQoveryContainers = async ({ - id, - actor, - actorId, - environmentId - }: TIntegrationAuthQoveryScopesDTO) => { + const getQoveryContainers = async ({ id, actor, actorId, environmentId }: TIntegrationAuthQoveryScopesDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); if (environmentId) { @@ -616,24 +466,12 @@ export const integrationAuthServiceFactory = ({ return []; }; - const getQoveryJobs = async ({ - id, - actor, - actorId, - environmentId - }: TIntegrationAuthQoveryScopesDTO) => { + const getQoveryJobs = async ({ id, actor, actorId, environmentId }: TIntegrationAuthQoveryScopesDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); if (environmentId) { @@ -655,24 +493,12 @@ export const integrationAuthServiceFactory = ({ return []; }; - const getRailwayEnvironments = async ({ - id, - actor, - actorId, - appId - }: TIntegrationAuthRailwayEnvDTO) => { + const getRailwayEnvironments = async ({ id, actor, actorId, appId }: TIntegrationAuthRailwayEnvDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); if (appId) { @@ -721,24 +547,12 @@ export const integrationAuthServiceFactory = ({ } return []; }; - const getRailwayServices = async ({ - id, - actor, - actorId, - appId - }: TIntegrationAuthRailwayServicesDTO) => { + const getRailwayServices = async ({ id, actor, actorId, appId }: TIntegrationAuthRailwayServicesDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); if (appId) { @@ -806,23 +620,12 @@ export const integrationAuthServiceFactory = ({ return []; }; - const getBitbucketWorkspaces = async ({ - actorId, - actor, - id - }: TIntegrationAuthBitbucketWorkspaceDTO) => { + const getBitbucketWorkspaces = async ({ actorId, actor, id }: TIntegrationAuthBitbucketWorkspaceDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); const workspaces: TBitbucketWorkspace[] = []; @@ -834,12 +637,11 @@ export const integrationAuthServiceFactory = ({ const { data }: { data: { values: TBitbucketWorkspace[]; next: string } } = await request.get( workspaceUrl, { - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" } - ); + }); if (data?.values.length > 0) { data.values.forEach((workspace) => { @@ -856,24 +658,12 @@ export const integrationAuthServiceFactory = ({ return workspaces; }; - const getNorthFlankSecretGroups = async ({ - id, - actor, - actorId, - appId - }: TIntegrationAuthNorthflankSecretGroupDTO) => { + const getNorthFlankSecretGroups = async ({ id, actor, actorId, appId }: TIntegrationAuthNorthflankSecretGroupDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); const secretGroups: { name: string; groupId: string }[] = []; @@ -923,41 +713,26 @@ export const integrationAuthServiceFactory = ({ return secretGroups; }; - const getTeamcityBuildConfigs = async ({ - appId, - id, - actorId, - actor - }: TGetIntegrationAuthTeamCityBuildConfigDTO) => { + const getTeamcityBuildConfigs = async ({ appId, id, actorId, actor }: TGetIntegrationAuthTeamCityBuildConfigDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const botKey = await projectBotService.getBotKey(integrationAuth.projectId); const { accessToken } = await getIntegrationAccessToken(integrationAuth, botKey); if (appId) { const { data: { buildType } - } = await request.get<{ buildType: TTeamCityBuildConfig[] }>( - `${integrationAuth.url}/app/rest/buildTypes`, - { - params: { - locator: `project:${appId}` - }, - headers: { - Authorization: `Bearer ${accessToken}`, - Accept: "application/json" - } + } = await request.get<{ buildType: TTeamCityBuildConfig[] }>(`${integrationAuth.url}/app/rest/buildTypes`, { + params: { + locator: `project:${appId}` + }, + headers: { + Authorization: `Bearer ${accessToken}`, + Accept: "application/json" } - ); + }); return buildType.map(({ name, id: buildConfigId }) => ({ name, @@ -967,39 +742,20 @@ export const integrationAuthServiceFactory = ({ return []; }; - const deleteIntegrationAuths = async ({ - projectId, - integration, - actor, - actorId - }: TDeleteIntegrationAuthsDTO) => { + const deleteIntegrationAuths = async ({ projectId, integration, actor, actorId }: TDeleteIntegrationAuthsDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Integrations - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); const integrations = await integrationAuthDAL.delete({ integration, projectId }); return integrations; }; - const deleteIntegrationAuthById = async ({ - id, - actorId, - actor - }: TDeleteIntegrationAuthByIdDTO) => { + const deleteIntegrationAuthById = async ({ id, actorId, actor }: TDeleteIntegrationAuthByIdDTO) => { const integrationAuth = await integrationAuthDAL.findById(id); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); const delIntegrationAuth = await integrationAuthDAL.transaction(async (tx) => { const doc = await integrationAuthDAL.deleteById(integrationAuth.id, tx); diff --git a/backend/src/services/integration-auth/integration-sync-secret.ts b/backend/src/services/integration-auth/integration-sync-secret.ts index 6fe196c52..abb6a7b1e 100644 --- a/backend/src/services/integration-auth/integration-sync-secret.ts +++ b/backend/src/services/integration-auth/integration-sync-secret.ts @@ -26,9 +26,7 @@ import { BadRequestError } from "@app/lib/errors"; import { Integrations, IntegrationUrls } from "./integration-list"; -const getSecretKeyValuePair = ( - secrets: Record -) => +const getSecretKeyValuePair = (secrets: Record) => Object.keys(secrets).reduce>((prev, key) => { // eslint-disable-next-line prev[key] = secrets?.[key] === null ? null : secrets?.[key]?.value; @@ -289,9 +287,7 @@ const syncSecretsAzureKeyVault = async ({ return result; }; - const getAzureKeyVaultSecrets = await paginateAzureKeyVaultSecrets( - `${integration.app}/secrets?api-version=7.3` - ); + const getAzureKeyVaultSecrets = await paginateAzureKeyVaultSecrets(`${integration.app}/secrets?api-version=7.3`); let lastSlashIndex: number; const res = ( @@ -301,14 +297,11 @@ const syncSecretsAzureKeyVault = async ({ lastSlashIndex = getAzureKeyVaultSecret.id.lastIndexOf("/"); } - const azureKeyVaultSecret = await request.get( - `${getAzureKeyVaultSecret.id}?api-version=7.3`, - { - headers: { - Authorization: `Bearer ${accessToken}` - } + const azureKeyVaultSecret = await request.get(`${getAzureKeyVaultSecret.id}?api-version=7.3`, { + headers: { + Authorization: `Bearer ${accessToken}` } - ); + }); return { ...azureKeyVaultSecret.data, @@ -701,11 +694,7 @@ const syncSecretsVercel = async ({ return false; } - if ( - integration.targetEnvironment === "preview" && - secret.gitBranch && - integration.path !== secret.gitBranch - ) { + if (integration.targetEnvironment === "preview" && secret.gitBranch && integration.path !== secret.gitBranch) { // case: secret on preview environment does not have same target git branch return false; } @@ -719,16 +708,13 @@ const syncSecretsVercel = async ({ if (vercelSecret.type === "encrypted") { // case: secret is encrypted -> need to decrypt const decryptedSecret = ( - await request.get( - `${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${vercelSecret.id}`, - { - params, - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } + await request.get(`${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${vercelSecret.id}`, { + params, + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" } - ) + }) ).data; res[vercelSecret.key] = decryptedSecret; @@ -798,47 +784,36 @@ const syncSecretsVercel = async ({ // Sync/push new secrets if (newSecrets.length > 0) { - await request.post( - `${IntegrationUrls.VERCEL_API_URL}/v10/projects/${integration.app}/env`, - newSecrets, - { - params, - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } + await request.post(`${IntegrationUrls.VERCEL_API_URL}/v10/projects/${integration.app}/env`, newSecrets, { + params, + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" } - ); + }); } for await (const secret of updateSecrets) { if (secret.type !== "sensitive") { const { id, ...updatedSecret } = secret; - await request.patch( - `${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${id}`, - updatedSecret, - { - params, - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } - } - ); - } - } - - for await (const secret of deleteSecrets) { - await request.delete( - `${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${secret.id}`, - { + await request.patch(`${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${id}`, updatedSecret, { params, headers: { Authorization: `Bearer ${accessToken}`, "Accept-Encoding": "application/json" } + }); + } + } + + for await (const secret of deleteSecrets) { + await request.delete(`${IntegrationUrls.VERCEL_API_URL}/v9/projects/${integration.app}/env/${secret.id}`, { + params, + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" } - ); + }); } }; @@ -1366,9 +1341,7 @@ const syncSecretsFlyio = async ({ ) ).data.data.app.secrets; - const deleteSecretsKeys = getSecretsRes - .filter((secret) => !(secret.name in secrets)) - .map((secret) => secret.name); + const deleteSecretsKeys = getSecretsRes.filter((secret) => !(secret.name in secrets)).map((secret) => secret.name); // unset (delete) secrets const DeleteSecrets = `mutation($input: UnsetSecretsInput!) { @@ -1593,9 +1566,7 @@ const syncSecretsGitLab = async ({ environment_scope: string; } - const gitLabApiUrl = integrationAuth.url - ? `${integrationAuth.url}/api` - : IntegrationUrls.GITLAB_API_URL; + const gitLabApiUrl = integrationAuth.url ? `${integrationAuth.url}/api` : IntegrationUrls.GITLAB_API_URL; const getAllEnvVariables = async (integrationAppId: string, accToken: string) => { const headers = { @@ -1605,8 +1576,7 @@ const syncSecretsGitLab = async ({ }; let allEnvVariables: GitLabSecret[] = []; - let url: string | null = - `${gitLabApiUrl}/v4/projects/${integrationAppId}/variables?per_page=100`; + let url: string | null = `${gitLabApiUrl}/v4/projects/${integrationAppId}/variables?per_page=100`; while (url) { const response = await request.get(url, { headers }); @@ -1740,29 +1710,21 @@ const syncSecretsSupabase = async ({ if ( !(secretObj.name in secrets) && // supbase reserved secret ref: https://supabase.com/docs/guides/functions/secrets#default-secrets - ![ - "SUPABASE_ANON_KEY", - "SUPABASE_SERVICE_ROLE_KEY", - "SUPABASE_DB_URL", - "SUPABASE_URL" - ].includes(secretObj.name) + !["SUPABASE_ANON_KEY", "SUPABASE_SERVICE_ROLE_KEY", "SUPABASE_DB_URL", "SUPABASE_URL"].includes(secretObj.name) ) { return secretObj.name; } return []; }); - await request.delete( - `${IntegrationUrls.SUPABASE_API_URL}/v1/projects/${integration.appId}/secrets`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - "Content-Type": "application/json", - "Accept-Encoding": "application/json" - }, - data: secretsToDelete - } - ); + await request.delete(`${IntegrationUrls.SUPABASE_API_URL}/v1/projects/${integration.appId}/secrets`, { + headers: { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + "Accept-Encoding": "application/json" + }, + data: secretsToDelete + }); }; /** @@ -1841,16 +1803,13 @@ const syncSecretsCheckly = async ({ // sync secrets to checkly global envars let getSecretsRes = ( - await request.get<{ key: string; value: string }[]>( - `${IntegrationUrls.CHECKLY_API_URL}/v1/variables`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json", - "X-Checkly-Account": integration.appId - } + await request.get<{ key: string; value: string }[]>(`${IntegrationUrls.CHECKLY_API_URL}/v1/variables`, { + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json", + "X-Checkly-Account": integration.appId } - ) + }) ).data.reduce( (obj, secret) => ({ ...obj, @@ -2260,15 +2219,12 @@ const syncSecretsTeamCity = async ({ for await (const key of Object.keys(res)) { if (!(key in secrets)) { // delete secret - await request.delete( - `${integrationAuth.url}/app/rest/projects/id:${integration.appId}/parameters/env.${key}`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - Accept: "application/json" - } + await request.delete(`${integrationAuth.url}/app/rest/projects/id:${integration.appId}/parameters/env.${key}`, { + headers: { + Authorization: `Bearer ${accessToken}`, + Accept: "application/json" } - ); + }); } } } @@ -2353,15 +2309,12 @@ const syncSecretsCloudflarePages = async ({ const getSecretsRes = ( await request.get<{ result: { deployment_configs: Record }> }; - }>( - `${IntegrationUrls.CLOUDFLARE_PAGES_API_URL}/client/v4/accounts/${accessId}/pages/projects/${integration.app}`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - Accept: "application/json" - } + }>(`${IntegrationUrls.CLOUDFLARE_PAGES_API_URL}/client/v4/accounts/${accessId}/pages/projects/${integration.app}`, { + headers: { + Authorization: `Bearer ${accessToken}`, + Accept: "application/json" } - ) + }) ).data.result.deployment_configs[integration.targetEnvironment as string].env_vars; // copy the secrets object, so we can set deleted keys to null @@ -2420,10 +2373,7 @@ const syncSecretsCloudflareWorkers = async ({ ).data.result; const secretsObj = Object.fromEntries( - Object.entries(getSecretKeyValuePair(secrets)).map(([key, val]) => [ - key, - { type: "secret_text", value: val } - ]) + Object.entries(getSecretKeyValuePair(secrets)).map(([key, val]) => [key, { type: "secret_text", value: val }]) ); // get deleted secrets list @@ -2463,13 +2413,11 @@ const syncSecretsCloudflareWorkers = async ({ }; } - const data: ConvertedSecret[] = Object.entries(secretsObj as SecretsObj).map( - ([name, secret]) => ({ - name, - text: secret.value, - type: "secret_text" - }) - ); + const data: ConvertedSecret[] = Object.entries(secretsObj as SecretsObj).map(([name, secret]) => ({ + name, + text: secret.value, + type: "secret_text" + })); await Promise.all( data.map(async (secret) => { @@ -2697,15 +2645,12 @@ const syncSecretsWindmill = async ({ // get secrets stored in windmill workspace const res = ( - await request.get( - `${IntegrationUrls.WINDMILL_API_URL}/w/${integration.appId}/variables/list`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - "Accept-Encoding": "application/json" - } + await request.get(`${IntegrationUrls.WINDMILL_API_URL}/w/${integration.appId}/variables/list`, { + headers: { + Authorization: `Bearer ${accessToken}`, + "Accept-Encoding": "application/json" } - ) + }) ).data.reduce( (obj, secret) => ({ ...obj, @@ -2858,15 +2803,12 @@ const syncSecretsCloud66 = async ({ for await (const key of Object.keys(res)) { if (!(key in secrets)) { // delete secret - await request.delete( - `${IntegrationUrls.CLOUD_66_API_URL}/3/stacks/${integration.appId}/environments/${key}`, - { - headers: { - Authorization: `Bearer ${accessToken}`, - Accept: "application/json" - } + await request.delete(`${IntegrationUrls.CLOUD_66_API_URL}/3/stacks/${integration.appId}/environments/${key}`, { + headers: { + Authorization: `Bearer ${accessToken}`, + Accept: "application/json" } - ); + }); } } }; @@ -2920,8 +2862,7 @@ const syncSecretsHasuraCloud = async ({ const res = await request.post( IntegrationUrls.HASURA_CLOUD_API_URL, { - query: - "query MyQuery($tenantId: uuid!) { getTenantEnv(tenantId: $tenantId) { hash envVars } }", + query: "query MyQuery($tenantId: uuid!) { getTenantEnv(tenantId: $tenantId) { hash envVars } }", variables: { tenantId: integration.appId } diff --git a/backend/src/services/integration-auth/integration-token.ts b/backend/src/services/integration-auth/integration-token.ts index 3e50e82ae..0907bd074 100644 --- a/backend/src/services/integration-auth/integration-token.ts +++ b/backend/src/services/integration-auth/integration-token.ts @@ -518,13 +518,7 @@ const exchangeRefreshHeroku = async ({ refreshToken }: { refreshToken: string }) * @param {String} obj.refreshToken - refresh token to use to get new access token for GitLab * @returns */ -const exchangeRefreshGitLab = async ({ - refreshToken, - url -}: { - url?: string | null; - refreshToken: string; -}) => { +const exchangeRefreshGitLab = async ({ refreshToken, url }: { url?: string | null; refreshToken: string }) => { const accessExpiresAt = new Date(); const appCfg = getConfig(); if (!appCfg.CLIENT_ID_GITLAB || !appCfg.CLIENT_SECRET_GITLAB) { @@ -628,19 +622,18 @@ const exchangeRefreshGCPSecretManager = async ({ const token = jwt.sign(payload, serviceAccount.private_key, { algorithm: "RS256" }); - const { data }: { data: ServiceAccountAccessTokenGCPSecretManagerResponse } = - await request.post( - IntegrationUrls.GCP_TOKEN_URL, - new URLSearchParams({ - grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", - assertion: token - }).toString(), - { - headers: { - "Content-Type": "application/x-www-form-urlencoded" - } + const { data }: { data: ServiceAccountAccessTokenGCPSecretManagerResponse } = await request.post( + IntegrationUrls.GCP_TOKEN_URL, + new URLSearchParams({ + grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", + assertion: token + }).toString(), + { + headers: { + "Content-Type": "application/x-www-form-urlencoded" } - ); + } + ); accessExpiresAt.setSeconds(accessExpiresAt.getSeconds() + data.expires_in); diff --git a/backend/src/services/integration/integration-dal.ts b/backend/src/services/integration/integration-dal.ts index 446af0bea..bada253c5 100644 --- a/backend/src/services/integration/integration-dal.ts +++ b/backend/src/services/integration/integration-dal.ts @@ -66,11 +66,7 @@ export const integrationDALFactory = (db: TDbClient) => { try { const integrations = await (tx || db)(TableName.Integration) .where(`${TableName.Environment}.projectId`, projectId) - .join( - TableName.Environment, - `${TableName.Integration}.envId`, - `${TableName.Environment}.id` - ) + .join(TableName.Environment, `${TableName.Integration}.envId`, `${TableName.Environment}.id`) .select(db.ref("name").withSchema(TableName.Environment).as("envName")) .select(db.ref("slug").withSchema(TableName.Environment).as("envSlug")) .select(db.ref("id").withSchema(TableName.Environment).as("envId")) @@ -99,11 +95,7 @@ export const integrationDALFactory = (db: TDbClient) => { .where("isActive", true) .where(`${TableName.Environment}.slug`, environment) .join(TableName.Environment, `${TableName.Integration}.envId`, `${TableName.Environment}.id`) - .join( - TableName.IntegrationAuth, - `${TableName.IntegrationAuth}.id`, - `${TableName.Integration}.integrationAuthId` - ) + .join(TableName.IntegrationAuth, `${TableName.IntegrationAuth}.id`, `${TableName.Integration}.integrationAuthId`) .select(db.ref("name").withSchema(TableName.Environment).as("envName")) .select(db.ref("slug").withSchema(TableName.Environment).as("envSlug")) .select(db.ref("id").withSchema(TableName.Environment).as("envId")) @@ -119,10 +111,7 @@ export const integrationDALFactory = (db: TDbClient) => { db.ref("refreshCiphertext").withSchema(TableName.IntegrationAuth).as("refreshCiphertextAu"), db.ref("refreshIV").withSchema(TableName.IntegrationAuth).as("refreshIVAu"), db.ref("refreshTag").withSchema(TableName.IntegrationAuth).as("refreshTagAu"), - db - .ref("accessIdCiphertext") - .withSchema(TableName.IntegrationAuth) - .as("accessIdCiphertextAu"), + db.ref("accessIdCiphertext").withSchema(TableName.IntegrationAuth).as("accessIdCiphertextAu"), db.ref("accessIdIV").withSchema(TableName.IntegrationAuth).as("accessIdIVAu"), db.ref("accessIdTag").withSchema(TableName.IntegrationAuth).as("accessIdTagAu"), db.ref("accessIV").withSchema(TableName.IntegrationAuth).as("accessIVAu"), diff --git a/backend/src/services/integration/integration-service.ts b/backend/src/services/integration/integration-service.ts index ba93b37fa..b7f74966e 100644 --- a/backend/src/services/integration/integration-service.ts +++ b/backend/src/services/integration/integration-service.ts @@ -1,10 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError } from "@app/lib/errors"; import { TProjectPermission } from "@app/lib/types"; @@ -12,11 +9,7 @@ import { TIntegrationAuthDALFactory } from "../integration-auth/integration-auth import { TSecretQueueFactory } from "../secret/secret-queue"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TIntegrationDALFactory } from "./integration-dal"; -import { - TCreateIntegrationDTO, - TDeleteIntegrationDTO, - TUpdateIntegrationDTO -} from "./integration-types"; +import { TCreateIntegrationDTO, TDeleteIntegrationDTO, TUpdateIntegrationDTO } from "./integration-types"; type TIntegrationServiceFactoryDep = { integrationDAL: TIntegrationDALFactory; @@ -57,21 +50,10 @@ export const integrationServiceFactory = ({ const integrationAuth = await integrationAuthDAL.findById(integrationAuthId); if (!integrationAuth) throw new BadRequestError({ message: "Integration auth not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integrationAuth.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integrationAuth.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); - const folder = await folderDAL.findBySecretPath( - integrationAuth.projectId, - sourceEnvironment, - secretPath - ); + const folder = await folderDAL.findBySecretPath(integrationAuth.projectId, sourceEnvironment, secretPath); if (!folder) throw new BadRequestError({ message: "Folder path not found" }); const integration = await integrationDAL.create({ @@ -116,15 +98,8 @@ export const integrationServiceFactory = ({ const integration = await integrationDAL.findById(id); if (!integration) throw new BadRequestError({ message: "Integration auth not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integration.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integration.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); const folder = await folderDAL.findBySecretPath(integration.projectId, environment, secretPath); if (!folder) throw new BadRequestError({ message: "Folder path not found" }); @@ -146,15 +121,8 @@ export const integrationServiceFactory = ({ const integration = await integrationDAL.findById(id); if (!integration) throw new BadRequestError({ message: "Integration auth not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - integration.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, integration.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); const deletedIntegration = await integrationDAL.deleteById(id); return { ...integration, ...deletedIntegration }; @@ -162,10 +130,7 @@ export const integrationServiceFactory = ({ const listIntegrationByProject = async ({ actor, actorId, projectId }: TProjectPermission) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const integrations = await integrationDAL.findByProjectId(projectId); return integrations; diff --git a/backend/src/services/org/incident-contacts-dal.ts b/backend/src/services/org/incident-contacts-dal.ts index c17516241..1979a9c3e 100644 --- a/backend/src/services/org/incident-contacts-dal.ts +++ b/backend/src/services/org/incident-contacts-dal.ts @@ -7,9 +7,7 @@ export type TIncidentContactsDALFactory = ReturnType { const create = async (orgId: string, email: string) => { try { - const [incidentContact] = await db(TableName.IncidentContact) - .insert({ orgId, email }) - .returning("*"); + const [incidentContact] = await db(TableName.IncidentContact).insert({ orgId, email }).returning("*"); return incidentContact; } catch (error) { throw new DatabaseError({ name: "Incident contact create", error }); @@ -38,10 +36,7 @@ export const incidentContactDALFactory = (db: TDbClient) => { const deleteById = async (id: string, orgId: string) => { try { - const [incidentContact] = await db(TableName.IncidentContact) - .where({ orgId, id }) - .delete() - .returning("*"); + const [incidentContact] = await db(TableName.IncidentContact).where({ orgId, id }).delete().returning("*"); return incidentContact; } catch (error) { throw new DatabaseError({ name: "Incident contact delete", error }); diff --git a/backend/src/services/org/org-dal.ts b/backend/src/services/org/org-dal.ts index 54237f70a..6629030d2 100644 --- a/backend/src/services/org/org-dal.ts +++ b/backend/src/services/org/org-dal.ts @@ -11,13 +11,7 @@ import { TUserEncryptionKeys } from "@app/db/schemas"; import { DatabaseError } from "@app/lib/errors"; -import { - buildFindFilter, - selectAllTableCols, - TFindFilter, - TFindOpt, - withTransaction -} from "@app/lib/knex"; +import { buildFindFilter, selectAllTableCols, TFindFilter, TFindOpt, withTransaction } from "@app/lib/knex"; export type TOrgDALFactory = ReturnType; @@ -36,11 +30,7 @@ export const orgDALFactory = (db: TDbClient) => { try { const org = await db(TableName.OrgMembership) .where({ userId }) - .join( - TableName.Organization, - `${TableName.OrgMembership}.orgId`, - `${TableName.Organization}.id` - ) + .join(TableName.Organization, `${TableName.OrgMembership}.orgId`, `${TableName.Organization}.id`) .select(selectAllTableCols(TableName.Organization)); return org; } catch (error) { @@ -105,10 +95,7 @@ export const orgDALFactory = (db: TDbClient) => { const deleteById = async (orgId: string, tx?: Knex) => { try { - const [org] = await (tx || db)(TableName.Organization) - .where({ id: orgId }) - .delete() - .returning("*"); + const [org] = await (tx || db)(TableName.Organization).where({ id: orgId }).delete().returning("*"); return org; } catch (error) { throw new DatabaseError({ error, name: "Update organization" }); @@ -142,26 +129,16 @@ export const orgDALFactory = (db: TDbClient) => { const updateMembershipById = async (id: string, data: TOrgMembershipsUpdate, tx?: Knex) => { try { - const [membership] = await (tx || db)(TableName.OrgMembership) - .where({ id }) - .update(data) - .returning("*"); + const [membership] = await (tx || db)(TableName.OrgMembership).where({ id }).update(data).returning("*"); return membership; } catch (error) { throw new DatabaseError({ error, name: "Update org membership" }); } }; - const updateMembership = async ( - filter: Partial, - data: TOrgMembershipsUpdate, - tx?: Knex - ) => { + const updateMembership = async (filter: Partial, data: TOrgMembershipsUpdate, tx?: Knex) => { try { - const membership = await (tx || db)(TableName.OrgMembership) - .where(filter) - .update(data) - .returning("*"); + const membership = await (tx || db)(TableName.OrgMembership).where(filter).update(data).returning("*"); return membership; } catch (error) { throw new DatabaseError({ error, name: "Update org memberships" }); @@ -170,10 +147,7 @@ export const orgDALFactory = (db: TDbClient) => { const deleteMembershipById = async (id: string, orgId: string, tx?: Knex) => { try { - const [membership] = await (tx || db)(TableName.OrgMembership) - .where({ id, orgId }) - .delete() - .returning("*"); + const [membership] = await (tx || db)(TableName.OrgMembership).where({ id, orgId }).delete().returning("*"); return membership; } catch (error) { throw new DatabaseError({ error, name: "Delete org membership" }); @@ -189,16 +163,11 @@ export const orgDALFactory = (db: TDbClient) => { // eslint-disable-next-line .where(buildFindFilter(filter)) .join(TableName.Users, `${TableName.Users}.id`, `${TableName.OrgMembership}.userId`) - .select( - selectAllTableCols(TableName.OrgMembership), - db.ref("email").withSchema(TableName.Users) - ); + .select(selectAllTableCols(TableName.OrgMembership), db.ref("email").withSchema(TableName.Users)); if (limit) void query.limit(limit); if (offset) void query.offset(offset); if (sort) { - void query.orderBy( - sort.map(([column, order, nulls]) => ({ column: column as string, order, nulls })) - ); + void query.orderBy(sort.map(([column, order, nulls]) => ({ column: column as string, order, nulls }))); } const res = await query; return res; diff --git a/backend/src/services/org/org-role-service.ts b/backend/src/services/org/org-role-service.ts index 8dfd0e0af..c48002d89 100644 --- a/backend/src/services/org/org-role-service.ts +++ b/backend/src/services/org/org-role-service.ts @@ -21,20 +21,10 @@ type TOrgRoleServiceFactoryDep = { export type TOrgRoleServiceFactory = ReturnType; -export const orgRoleServiceFactory = ({ - orgRoleDAL, - permissionService -}: TOrgRoleServiceFactoryDep) => { - const createRole = async ( - userId: string, - orgId: string, - data: Omit - ) => { +export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRoleServiceFactoryDep) => { + const createRole = async (userId: string, orgId: string, data: Omit) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.Role - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Role); const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId }); if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" }); const role = await orgRoleDAL.create({ @@ -45,17 +35,9 @@ export const orgRoleServiceFactory = ({ return role; }; - const updateRole = async ( - userId: string, - orgId: string, - roleId: string, - data: Omit - ) => { + const updateRole = async (userId: string, orgId: string, roleId: string, data: Omit) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Edit, - OrgPermissionSubjects.Role - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Role); if (data?.slug) { const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId }); if (existingRole && existingRole.id !== roleId) @@ -71,10 +53,7 @@ export const orgRoleServiceFactory = ({ const deleteRole = async (userId: string, orgId: string, roleId: string) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Delete, - OrgPermissionSubjects.Role - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Role); const [deletedRole] = await orgRoleDAL.delete({ id: roleId, orgId }); if (!deleteRole) throw new BadRequestError({ message: "Role not found", name: "Update role" }); @@ -83,10 +62,7 @@ export const orgRoleServiceFactory = ({ const listRoles = async (userId: string, orgId: string) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Role - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Role); const customRoles = await orgRoleDAL.find({ orgId }); const roles = [ { diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index 4b0ae357d..a393edcb5 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -5,10 +5,7 @@ import jwt from "jsonwebtoken"; import { OrgMembershipRole, OrgMembershipStatus } from "@app/db/schemas"; import { TProjects } from "@app/db/schemas/projects"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { - OrgPermissionActions, - OrgPermissionSubjects -} from "@app/ee/services/permission/org-permission"; +import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { TSamlConfigDALFactory } from "@app/ee/services/saml-config/saml-config-dal"; import { getConfig } from "@app/lib/config/env"; @@ -74,8 +71,7 @@ export const orgServiceFactory = ({ const findOrganizationById = async (userId: string, orgId: string) => { await permissionService.getUserOrgPermission(userId, orgId); const org = await orgDAL.findOrgById(orgId); - if (!org) - throw new BadRequestError({ name: "Org not found", message: "Organization not found" }); + if (!org) throw new BadRequestError({ name: "Org not found", message: "Organization not found" }); return org; }; /* @@ -90,10 +86,7 @@ export const orgServiceFactory = ({ * */ const findAllOrgMembers = async (userId: string, orgId: string) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Member - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Member); const members = await orgDAL.findAllOrgMembers(orgId); return members; @@ -101,14 +94,9 @@ export const orgServiceFactory = ({ const findAllWorkspaces = async ({ actor, actorId, orgId }: TFindAllWorkspacesDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.Workspace - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Workspace); - const organizationWorkspaceIds = new Set( - (await projectDAL.find({ orgId })).map((workspace) => workspace.id) - ); + const organizationWorkspaceIds = new Set((await projectDAL.find({ orgId })).map((workspace) => workspace.id)); let workspaces: (TProjects & { organization: string } & { environments: { @@ -134,13 +122,9 @@ export const orgServiceFactory = ({ * */ const updateOrgName = async (userId: string, orgId: string, name: string) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Edit, - OrgPermissionSubjects.Settings - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); const org = await orgDAL.updateById(orgId, { name }); - if (!org) - throw new BadRequestError({ name: "Org not found", message: "Organization not found" }); + if (!org) throw new BadRequestError({ name: "Org not found", message: "Organization not found" }); return org; }; /* @@ -222,29 +206,19 @@ export const orgServiceFactory = ({ * Org membership management * Not another service because it has close ties with how an org works doesn't make sense to seperate them * */ - const updateOrgMembership = async ({ - role, - orgId, - userId, - membershipId - }: TUpdateOrgMembershipDTO) => { + const updateOrgMembership = async ({ role, orgId, userId, membershipId }: TUpdateOrgMembershipDTO) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Edit, - OrgPermissionSubjects.Member - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member); const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole); if (isCustomRole) { const customRole = await orgRoleDAL.findOne({ slug: role, orgId }); - if (!customRole) - throw new BadRequestError({ name: "Update membership", message: "Role not found" }); + if (!customRole) throw new BadRequestError({ name: "Update membership", message: "Role not found" }); const plan = await licenseService.getPlan(orgId); if (!plan?.rbac) throw new BadRequestError({ - message: - "Failed to assign custom role due to RBAC restriction. Upgrade plan to assign custom role to member." + message: "Failed to assign custom role due to RBAC restriction. Upgrade plan to assign custom role to member." }); const [membership] = await orgDAL.updateMembership( @@ -257,10 +231,7 @@ export const orgServiceFactory = ({ return membership; } - const [membership] = await orgDAL.updateMembership( - { id: membershipId, orgId }, - { role, roleId: null } - ); + const [membership] = await orgDAL.updateMembership({ id: membershipId, orgId }, { role, roleId: null }); return membership; }; /* @@ -268,10 +239,7 @@ export const orgServiceFactory = ({ */ const inviteUserToOrganization = async ({ orgId, userId, inviteeEmail }: TInviteUserToOrgDTO) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.Member - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Member); const samlCfg = await samlConfigDAL.findOne({ orgId }); if (samlCfg && samlCfg.isActive) { @@ -284,8 +252,7 @@ export const orgServiceFactory = ({ // case: limit imposed on number of members allowed // case: number of members used exceeds the number of members allowed throw new BadRequestError({ - message: - "Failed to invite member due to member limit reached. Upgrade plan to invite more members." + message: "Failed to invite member due to member limit reached. Upgrade plan to invite more members." }); } const invitee = await orgDAL.transaction(async (tx) => { @@ -293,10 +260,7 @@ export const orgServiceFactory = ({ if (inviteeUser) { // if user already exist means its already part of infisical // Thus the signup flow is not needed anymore - const [inviteeMembership] = await orgDAL.findMembership( - { orgId, userId: inviteeUser.id }, - { tx } - ); + const [inviteeMembership] = await orgDAL.findMembership({ orgId, userId: inviteeUser.id }, { tx }); if (inviteeMembership && inviteeMembership.status === OrgMembershipStatus.Accepted) { throw new BadRequestError({ message: "Failed to invite an existing member of org", @@ -432,10 +396,7 @@ export const orgServiceFactory = ({ const deleteOrgMembership = async ({ orgId, userId, membershipId }: TDeleteOrgMembershipDTO) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Delete, - OrgPermissionSubjects.Member - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Member); const membership = await orgDAL.deleteMembershipById(membershipId, orgId); @@ -448,20 +409,14 @@ export const orgServiceFactory = ({ * */ const findIncidentContacts = async (userId: string, orgId: string) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Read, - OrgPermissionSubjects.IncidentAccount - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.IncidentAccount); const incidentContacts = await incidentContactDAL.findByOrgId(orgId); return incidentContacts; }; const createIncidentContact = async (userId: string, orgId: string, email: string) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.IncidentAccount - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.IncidentAccount); const doesIncidentContactExist = await incidentContactDAL.findOne(orgId, { email }); if (doesIncidentContactExist) { throw new BadRequestError({ @@ -476,10 +431,7 @@ export const orgServiceFactory = ({ const deleteIncidentContact = async (userId: string, orgId: string, id: string) => { const { permission } = await permissionService.getUserOrgPermission(userId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Delete, - OrgPermissionSubjects.IncidentAccount - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.IncidentAccount); const incidentContact = await incidentContactDAL.deleteById(id, orgId); return incidentContact; diff --git a/backend/src/services/project-bot/project-bot-dal.ts b/backend/src/services/project-bot/project-bot-dal.ts index 39a8628b8..7f342f0ae 100644 --- a/backend/src/services/project-bot/project-bot-dal.ts +++ b/backend/src/services/project-bot/project-bot-dal.ts @@ -15,11 +15,7 @@ export const projectBotDALFactory = (db: TDbClient) => { const bot = await (tx || db)(TableName.ProjectBot) .where(filter) .leftJoin(TableName.Users, `${TableName.ProjectBot}.senderId`, `${TableName.Users}.id`) - .leftJoin( - TableName.UserEncryptionKey, - `${TableName.UserEncryptionKey}.userId`, - `${TableName.Users}.id` - ) + .leftJoin(TableName.UserEncryptionKey, `${TableName.UserEncryptionKey}.userId`, `${TableName.Users}.id`) .select(selectAllTableCols(TableName.ProjectBot)) .select(db.ref("publicKey").withSchema(TableName.UserEncryptionKey).as("senderPubKey")) .first(); diff --git a/backend/src/services/project-bot/project-bot-service.ts b/backend/src/services/project-bot/project-bot-service.ts index 4bd80bc21..5478aadfa 100644 --- a/backend/src/services/project-bot/project-bot-service.ts +++ b/backend/src/services/project-bot/project-bot-service.ts @@ -2,10 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { SecretEncryptionAlgo, SecretKeyEncoding } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; import { decryptAsymmetric, @@ -28,10 +25,7 @@ type TProjectBotServiceFactoryDep = { export type TProjectBotServiceFactory = ReturnType; -export const projectBotServiceFactory = ({ - projectBotDAL, - permissionService -}: TProjectBotServiceFactoryDep) => { +export const projectBotServiceFactory = ({ projectBotDAL, permissionService }: TProjectBotServiceFactoryDep) => { const getBotKey = async (projectId: string) => { const appCfg = getConfig(); const encryptionKey = appCfg.ENCRYPTION_KEY; @@ -79,10 +73,7 @@ export const projectBotServiceFactory = ({ const findBotByProjectId = async ({ actorId, actor, projectId }: TProjectPermission) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Integrations - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); const appCfg = getConfig(); const bot = await projectBotDAL.transaction(async (tx) => { @@ -108,10 +99,7 @@ export const projectBotServiceFactory = ({ ); } if (appCfg.ENCRYPTION_KEY) { - const { iv, tag, ciphertext } = encryptSymmetric128BitHexKeyUTF8( - privateKey, - appCfg.ENCRYPTION_KEY - ); + const { iv, tag, ciphertext } = encryptSymmetric128BitHexKeyUTF8(privateKey, appCfg.ENCRYPTION_KEY); return projectBotDAL.create( { name: "Infisical Bot", @@ -132,25 +120,12 @@ export const projectBotServiceFactory = ({ return bot; }; - const setBotActiveState = async ({ - actor, - botId, - botKey, - actorId, - isActive - }: TSetActiveStateDTO) => { + const setBotActiveState = async ({ actor, botId, botKey, actorId, isActive }: TSetActiveStateDTO) => { const bot = await projectBotDAL.findById(botId); if (!bot) throw new BadRequestError({ message: "Bot not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - bot.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Integrations - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, bot.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); if (isActive) { if (!botKey?.nonce || !botKey?.encryptedKey) { diff --git a/backend/src/services/project-env/project-env-dal.ts b/backend/src/services/project-env/project-env-dal.ts index 9b196f08f..42a234298 100644 --- a/backend/src/services/project-env/project-env-dal.ts +++ b/backend/src/services/project-env/project-env-dal.ts @@ -12,9 +12,7 @@ export const projectEnvDALFactory = (db: TDbClient) => { const findBySlugs = async (projectId: string, env: string[], tx?: Knex) => { try { - const envs = await (tx || db)(TableName.Environment) - .where("projectId", projectId) - .whereIn("slug", env); + const envs = await (tx || db)(TableName.Environment).where("projectId", projectId).whereIn("slug", env); return envs; } catch (error) { throw new DatabaseError({ error, name: "Find by slugs" }); @@ -31,12 +29,7 @@ export const projectEnvDALFactory = (db: TDbClient) => { return lastPos?.position || 0; }; - const updateAllPosition = async ( - projectId: string, - pos: number, - targetPos: number, - tx?: Knex - ) => { + const updateAllPosition = async (projectId: string, pos: number, targetPos: number, tx?: Knex) => { try { if (targetPos === -1) { // this means delete diff --git a/backend/src/services/project-env/project-env-service.ts b/backend/src/services/project-env/project-env-service.ts index d95bb7950..c430548cf 100644 --- a/backend/src/services/project-env/project-env-service.ts +++ b/backend/src/services/project-env/project-env-service.ts @@ -2,10 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError } from "@app/lib/errors"; import { TProjectDALFactory } from "../project/project-dal"; @@ -32,10 +29,7 @@ export const projectEnvServiceFactory = ({ }: TProjectEnvServiceFactoryDep) => { const createEnvironment = async ({ projectId, actorId, actor, name, slug }: TCreateEnvDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Environments - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Environments); const envs = await projectEnvDAL.find({ projectId }); const existingEnv = envs.find(({ slug: envSlug }) => envSlug === slug); @@ -65,20 +59,9 @@ export const projectEnvServiceFactory = ({ return env; }; - const updateEnvironment = async ({ - projectId, - slug, - actor, - actorId, - name, - id, - position - }: TUpdateEnvDTO) => { + const updateEnvironment = async ({ projectId, slug, actor, actorId, name, id, position }: TUpdateEnvDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Environments - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Environments); const oldEnv = await projectEnvDAL.findOne({ id, projectId }); if (!oldEnv) throw new BadRequestError({ message: "Environment not found" }); @@ -104,10 +87,7 @@ export const projectEnvServiceFactory = ({ const deleteEnvironment = async ({ projectId, actor, actorId, id }: TDeleteEnvDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Environments - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Environments); const env = await projectEnvDAL.transaction(async (tx) => { const [doc] = await projectEnvDAL.delete({ id, projectId }, tx); diff --git a/backend/src/services/project-key/project-key-dal.ts b/backend/src/services/project-key/project-key-dal.ts index 5cec6014a..7423a48de 100644 --- a/backend/src/services/project-key/project-key-dal.ts +++ b/backend/src/services/project-key/project-key-dal.ts @@ -15,11 +15,7 @@ export const projectKeyDALFactory = (db: TDbClient) => { try { const projectKey = await db(TableName.ProjectKeys) .join(TableName.Users, `${TableName.ProjectKeys}.senderId`, `${TableName.Users}.id`) - .join( - TableName.UserEncryptionKey, - `${TableName.UserEncryptionKey}.userId`, - `${TableName.Users}.id` - ) + .join(TableName.UserEncryptionKey, `${TableName.UserEncryptionKey}.userId`, `${TableName.Users}.id`) .where({ projectId, receiverId: userId }) .orderBy("createdAt", "desc", "last") .select(selectAllTableCols(TableName.ProjectKeys)) @@ -38,11 +34,7 @@ export const projectKeyDALFactory = (db: TDbClient) => { const pubKeys = await db(TableName.ProjectMembership) .where({ projectId }) .join(TableName.Users, `${TableName.ProjectMembership}.userId`, `${TableName.Users}.id`) - .join( - TableName.UserEncryptionKey, - `${TableName.Users}.id`, - `${TableName.UserEncryptionKey}.userId` - ) + .join(TableName.UserEncryptionKey, `${TableName.Users}.id`, `${TableName.UserEncryptionKey}.userId`) .select("userId", "publicKey"); return pubKeys; } catch (error) { diff --git a/backend/src/services/project-key/project-key-service.ts b/backend/src/services/project-key/project-key-service.ts index 76694217f..e7ebc23ee 100644 --- a/backend/src/services/project-key/project-key-service.ts +++ b/backend/src/services/project-key/project-key-service.ts @@ -1,10 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError } from "@app/lib/errors"; import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; @@ -33,10 +30,7 @@ export const projectKeyServiceFactory = ({ encryptedKey }: TUploadProjectKeyDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Member - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member); const receiverMembership = await projectMembershipDAL.findOne({ userId: receiverId, @@ -59,10 +53,7 @@ export const projectKeyServiceFactory = ({ const getProjectPublicKeys = async ({ actor, actorId, projectId }: TGetLatestProjectKeyDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Member - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member); return projectKeyDAL.findAllProjectUserPubKeys(projectId); }; diff --git a/backend/src/services/project-membership/project-membership-service.ts b/backend/src/services/project-membership/project-membership-service.ts index a71aab944..862c19384 100644 --- a/backend/src/services/project-membership/project-membership-service.ts +++ b/backend/src/services/project-membership/project-membership-service.ts @@ -3,10 +3,7 @@ import { ForbiddenError } from "@casl/ability"; import { OrgMembershipStatus, ProjectMembershipRole, TableName } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError } from "@app/lib/errors"; import { groupBy } from "@app/lib/fn"; @@ -53,25 +50,14 @@ export const projectMembershipServiceFactory = ({ }: TProjectMembershipServiceFactoryDep) => { const getProjectMemberships = async ({ actorId, actor, projectId }: TGetProjectMembershipDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Member - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member); return projectMembershipDAL.findAllProjectMembers(projectId); }; - const inviteUserToProject = async ({ - actorId, - actor, - projectId, - email - }: TInviteUserToProjectDTO) => { + const inviteUserToProject = async ({ actorId, actor, projectId, email }: TInviteUserToProjectDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Member - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Member); const invitee = await userDAL.findOne({ email }); if (!invitee || !invitee.isAccepted) @@ -126,37 +112,25 @@ export const projectMembershipServiceFactory = ({ return { invitee, latestKey }; }; - const addUsersToProject = async ({ - projectId, - actorId, - actor, - members - }: TAddUsersToWorkspaceDTO) => { + const addUsersToProject = async ({ projectId, actorId, actor, members }: TAddUsersToWorkspaceDTO) => { const project = await projectDAL.findById(projectId); if (!project) throw new BadRequestError({ message: "Project not found" }); const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Member - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Member); const orgMembers = await orgDAL.findMembership({ orgId: project.orgId, $in: { - [`${TableName.OrgMembership}.id` as "id"]: members.map( - ({ orgMembershipId }) => orgMembershipId - ) + [`${TableName.OrgMembership}.id` as "id"]: members.map(({ orgMembershipId }) => orgMembershipId) } }); - if (orgMembers.length !== members.length) - throw new BadRequestError({ message: "Some users are not part of org" }); + if (orgMembers.length !== members.length) throw new BadRequestError({ message: "Some users are not part of org" }); const existingMembers = await projectMembershipDAL.find({ projectId, $in: { userId: orgMembers.map(({ userId }) => userId).filter(Boolean) as string[] } }); - if (existingMembers.length) - throw new BadRequestError({ message: "Some users are already part of project" }); + if (existingMembers.length) throw new BadRequestError({ message: "Some users are already part of project" }); await projectMembershipDAL.transaction(async (tx) => { await projectMembershipDAL.insertMany( @@ -203,24 +177,17 @@ export const projectMembershipServiceFactory = ({ role }: TUpdateProjectMembershipDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Member - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member); - const isCustomRole = !Object.values(ProjectMembershipRole).includes( - role as ProjectMembershipRole - ); + const isCustomRole = !Object.values(ProjectMembershipRole).includes(role as ProjectMembershipRole); if (isCustomRole) { const customRole = await projectRoleDAL.findOne({ slug: role, projectId }); - if (!customRole) - throw new BadRequestError({ name: "Update project membership", message: "Role not found" }); + if (!customRole) throw new BadRequestError({ name: "Update project membership", message: "Role not found" }); const project = await projectDAL.findById(customRole.projectId); const plan = await licenseService.getPlan(project.orgId); if (!plan?.rbac) throw new BadRequestError({ - message: - "Failed to assign custom role due to RBAC restriction. Upgrade plan to assign custom role to member." + message: "Failed to assign custom role due to RBAC restriction. Upgrade plan to assign custom role to member." }); const [membership] = await projectMembershipDAL.update( @@ -233,30 +200,16 @@ export const projectMembershipServiceFactory = ({ return membership; } - const [membership] = await projectMembershipDAL.update( - { id: membershipId, projectId }, - { role, roleId: null } - ); + const [membership] = await projectMembershipDAL.update({ id: membershipId, projectId }, { role, roleId: null }); return membership; }; - const deleteProjectMembership = async ({ - actorId, - actor, - projectId, - membershipId - }: TDeleteProjectMembershipDTO) => { + const deleteProjectMembership = async ({ actorId, actor, projectId, membershipId }: TDeleteProjectMembershipDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Member - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Member); const membership = await projectMembershipDAL.transaction(async (tx) => { - const [deletedMembership] = await projectMembershipDAL.delete( - { projectId, id: membershipId }, - tx - ); + const [deletedMembership] = await projectMembershipDAL.delete({ projectId, id: membershipId }, tx); await projectKeyDAL.delete({ receiverId: deletedMembership.userId, projectId }, tx); return deletedMembership; }); diff --git a/backend/src/services/project-role/project-role-service.ts b/backend/src/services/project-role/project-role-service.ts index 8e86b45fb..4c0633712 100644 --- a/backend/src/services/project-role/project-role-service.ts +++ b/backend/src/services/project-role/project-role-service.ts @@ -18,18 +18,12 @@ import { TProjectRoleDALFactory } from "./project-role-dal"; type TProjectRoleServiceFactoryDep = { projectRoleDAL: TProjectRoleDALFactory; - permissionService: Pick< - TPermissionServiceFactory, - "getProjectPermission" | "getUserProjectPermission" - >; + permissionService: Pick; }; export type TProjectRoleServiceFactory = ReturnType; -export const projectRoleServiceFactory = ({ - projectRoleDAL, - permissionService -}: TProjectRoleServiceFactoryDep) => { +export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }: TProjectRoleServiceFactoryDep) => { const createRole = async ( actor: ActorType, actorId: string, @@ -37,10 +31,7 @@ export const projectRoleServiceFactory = ({ data: Omit ) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Role - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Role); const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId }); if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" }); const role = await projectRoleDAL.create({ @@ -59,10 +50,7 @@ export const projectRoleServiceFactory = ({ data: Omit ) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Role - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Role); if (data?.slug) { const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId }); if (existingRole && existingRole.id !== roleId) @@ -76,17 +64,9 @@ export const projectRoleServiceFactory = ({ return updatedRole; }; - const deleteRole = async ( - actor: ActorType, - actorId: string, - projectId: string, - roleId: string - ) => { + const deleteRole = async (actor: ActorType, actorId: string, projectId: string, roleId: string) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Role - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Role); const [deletedRole] = await projectRoleDAL.delete({ id: roleId, projectId }); if (!deleteRole) throw new BadRequestError({ message: "Role not found", name: "Update role" }); @@ -95,10 +75,7 @@ export const projectRoleServiceFactory = ({ const listRoles = async (actor: ActorType, actorId: string, projectId: string) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Role - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role); const customRoles = await projectRoleDAL.find({ projectId }); const roles = [ { @@ -151,10 +128,7 @@ export const projectRoleServiceFactory = ({ }; const getUserPermission = async (userId: string, projectId: string) => { - const { permission, membership } = await permissionService.getUserProjectPermission( - userId, - projectId - ); + const { permission, membership } = await permissionService.getUserProjectPermission(userId, projectId); return { permissions: packRules(permission.rules), membership }; }; diff --git a/backend/src/services/project/project-dal.ts b/backend/src/services/project/project-dal.ts index c286c379f..b57fdffe1 100644 --- a/backend/src/services/project/project-dal.ts +++ b/backend/src/services/project/project-dal.ts @@ -12,16 +12,8 @@ export const projectDALFactory = (db: TDbClient) => { try { const workspaces = await db(TableName.ProjectMembership) .where({ userId }) - .join( - TableName.Project, - `${TableName.ProjectMembership}.projectId`, - `${TableName.Project}.id` - ) - .leftJoin( - TableName.Environment, - `${TableName.Environment}.projectId`, - `${TableName.Project}.id` - ) + .join(TableName.Project, `${TableName.ProjectMembership}.projectId`, `${TableName.Project}.id`) + .leftJoin(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`) .select( selectAllTableCols(TableName.Project), db.ref("id").withSchema(TableName.Project).as("_id"), @@ -60,16 +52,8 @@ export const projectDALFactory = (db: TDbClient) => { try { const workspaces = await db(TableName.IdentityProjectMembership) .where({ identityId }) - .join( - TableName.Project, - `${TableName.IdentityProjectMembership}.projectId`, - `${TableName.Project}.id` - ) - .leftJoin( - TableName.Environment, - `${TableName.Environment}.projectId`, - `${TableName.Project}.id` - ) + .join(TableName.Project, `${TableName.IdentityProjectMembership}.projectId`, `${TableName.Project}.id`) + .leftJoin(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`) .select( selectAllTableCols(TableName.Project), db.ref("id").withSchema(TableName.Project).as("_id"), @@ -110,16 +94,8 @@ export const projectDALFactory = (db: TDbClient) => { try { const workspaces = await db(TableName.ProjectMembership) .where(`${TableName.Project}.id`, id) - .join( - TableName.Project, - `${TableName.ProjectMembership}.projectId`, - `${TableName.Project}.id` - ) - .join( - TableName.Environment, - `${TableName.Environment}.projectId`, - `${TableName.Project}.id` - ) + .join(TableName.Project, `${TableName.ProjectMembership}.projectId`, `${TableName.Project}.id`) + .join(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`) .select( selectAllTableCols(TableName.Project), db.ref("id").withSchema(TableName.Project).as("_id"), diff --git a/backend/src/services/project/project-service.ts b/backend/src/services/project/project-service.ts index df1168578..08d75b0dd 100644 --- a/backend/src/services/project/project-service.ts +++ b/backend/src/services/project/project-service.ts @@ -3,15 +3,9 @@ import slugify from "@sindresorhus/slugify"; import { ProjectMembershipRole } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { - OrgPermissionActions, - OrgPermissionSubjects -} from "@app/ee/services/permission/org-permission"; +import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; import { createSecretBlindIndex } from "@app/lib/crypto"; import { BadRequestError } from "@app/lib/errors"; @@ -56,10 +50,7 @@ export const projectServiceFactory = ({ * */ const createProject = async ({ orgId, actor, actorId, workspaceName }: TCreateProjectDTO) => { const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); - ForbiddenError.from(permission).throwUnlessCan( - OrgPermissionActions.Create, - OrgPermissionSubjects.Workspace - ); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Workspace); const appCfg = getConfig(); const blindIndex = createSecretBlindIndex(appCfg.ROOT_ENCRYPTION_KEY, appCfg.ENCRYPTION_KEY); @@ -69,8 +60,7 @@ export const projectServiceFactory = ({ // case: limit imposed on number of workspaces allowed // case: number of workspaces used exceeds the number of workspaces allowed throw new BadRequestError({ - message: - "Failed to create workspace due to plan limit reached. Upgrade plan to add more workspaces." + message: "Failed to create workspace due to plan limit reached. Upgrade plan to add more workspaces." }); } @@ -118,10 +108,7 @@ export const projectServiceFactory = ({ const deleteProject = async ({ actor, actorId, projectId }: TDeleteProjectDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Project - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project); const deletedProject = await projectDAL.deleteById(projectId); return deletedProject; @@ -144,26 +131,15 @@ export const projectServiceFactory = ({ autoCapitalization }: TGetProjectDTO & { autoCapitalization: boolean }) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Settings - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); const updatedProject = await projectDAL.updateById(projectId, { autoCapitalization }); return updatedProject; }; - const updateName = async ({ - projectId, - actor, - actorId, - name - }: TGetProjectDTO & { name: string }) => { + const updateName = async ({ projectId, actor, actorId, name }: TGetProjectDTO & { name: string }) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Settings - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); const updatedProject = await projectDAL.updateById(projectId, { name }); return updatedProject; diff --git a/backend/src/services/secret-blind-index/secret-blind-index-dal.ts b/backend/src/services/secret-blind-index/secret-blind-index-dal.ts index 8c492831b..8fa60cde7 100644 --- a/backend/src/services/secret-blind-index/secret-blind-index-dal.ts +++ b/backend/src/services/secret-blind-index/secret-blind-index-dal.ts @@ -13,16 +13,8 @@ export const secretBlindIndexDALFactory = (db: TDbClient) => { const countOfSecretsWithNullSecretBlindIndex = async (projectId: string, tx?: Knex) => { try { const doc = await (tx || db)(TableName.Secret) - .leftJoin( - TableName.SecretFolder, - `${TableName.SecretFolder}.id`, - `${TableName.Secret}.folderId` - ) - .leftJoin( - TableName.Environment, - `${TableName.Environment}.id`, - `${TableName.SecretFolder}.envId` - ) + .leftJoin(TableName.SecretFolder, `${TableName.SecretFolder}.id`, `${TableName.Secret}.folderId`) + .leftJoin(TableName.Environment, `${TableName.Environment}.id`, `${TableName.SecretFolder}.envId`) .where({ projectId }) .whereNull("secretBlindIndex") .count(`${TableName.Secret}.id` as "id"); @@ -35,16 +27,8 @@ export const secretBlindIndexDALFactory = (db: TDbClient) => { const findAllSecretsByProjectId = async (projectId: string, tx?: Knex) => { try { const docs = await (tx || db)(TableName.Secret) - .leftJoin( - TableName.SecretFolder, - `${TableName.SecretFolder}.id`, - `${TableName.Secret}.folderId` - ) - .leftJoin( - TableName.Environment, - `${TableName.Environment}.id`, - `${TableName.SecretFolder}.envId` - ) + .leftJoin(TableName.SecretFolder, `${TableName.SecretFolder}.id`, `${TableName.Secret}.folderId`) + .leftJoin(TableName.Environment, `${TableName.Environment}.id`, `${TableName.SecretFolder}.envId`) .where({ projectId }) .whereNull("secretBlindIndex") .select(selectAllTableCols(TableName.Secret)) @@ -61,16 +45,8 @@ export const secretBlindIndexDALFactory = (db: TDbClient) => { const findSecretsByProjectId = async (projectId: string, secretIds: string[], tx?: Knex) => { try { const docs = await (tx || db)(TableName.Secret) - .leftJoin( - TableName.SecretFolder, - `${TableName.SecretFolder}.id`, - `${TableName.Secret}.folderId` - ) - .leftJoin( - TableName.Environment, - `${TableName.Environment}.id`, - `${TableName.SecretFolder}.envId` - ) + .leftJoin(TableName.SecretFolder, `${TableName.SecretFolder}.id`, `${TableName.Secret}.folderId`) + .leftJoin(TableName.Environment, `${TableName.Environment}.id`, `${TableName.SecretFolder}.envId`) .where({ projectId }) .whereIn(`${TableName.Secret}.id`, secretIds) .whereNull("secretBlindIndex") 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 0c18ddedc..bb565e295 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 @@ -24,11 +24,7 @@ export const secretBlindIndexServiceFactory = ({ permissionService, secretDAL }: TSecretBlindIndexServiceFactoryDep) => { - const getSecretBlindIndexStatus = async ({ - actor, - projectId, - actorId - }: TGetProjectBlindIndexStatusDTO) => { + const getSecretBlindIndexStatus = async ({ actor, projectId, actorId }: TGetProjectBlindIndexStatusDTO) => { await permissionService.getProjectPermission(actor, actorId, projectId); const secretCount = await secretBlindIndexDAL.countOfSecretsWithNullSecretBlindIndex(projectId); @@ -57,15 +53,13 @@ export const secretBlindIndexServiceFactory = ({ } const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId }); - if (!blindIndexCfg) - throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" }); + if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" }); const secrets = await secretBlindIndexDAL.findSecretsByProjectId( projectId, secretsToUpdate.map(({ secretId }) => secretId) ); - if (secrets.length !== secretsToUpdate.length) - throw new BadRequestError({ message: "Secret not found" }); + if (secrets.length !== secretsToUpdate.length) throw new BadRequestError({ message: "Secret not found" }); const operations = await Promise.all( secretsToUpdate.map(async ({ secretName, secretId: id }) => { diff --git a/backend/src/services/secret-folder/secret-folder-dal.ts b/backend/src/services/secret-folder/secret-folder-dal.ts index 505f9a957..023d039ca 100644 --- a/backend/src/services/secret-folder/secret-folder-dal.ts +++ b/backend/src/services/secret-folder/secret-folder-dal.ts @@ -1,12 +1,7 @@ import { Knex } from "knex"; import { TDbClient } from "@app/db"; -import { - TableName, - TProjectEnvironments, - TSecretFolders, - TSecretFoldersUpdate -} from "@app/db/schemas"; +import { TableName, TProjectEnvironments, TSecretFolders, TSecretFoldersUpdate } from "@app/db/schemas"; import { BadRequestError, DatabaseError } from "@app/lib/errors"; import { groupBy, removeTrailingSlash } from "@app/lib/fn"; import { ormify, selectAllTableCols } from "@app/lib/knex"; @@ -16,14 +11,10 @@ export const validateFolderName = (folderName: string) => { return validNameRegex.test(folderName); }; -const sqlFindMultipleFolderByEnvPathQuery = ( - db: Knex, - query: Array<{ envId: string; secretPath: string }> -) => { +const sqlFindMultipleFolderByEnvPathQuery = (db: Knex, query: Array<{ envId: string; secretPath: string }>) => { // this is removing an trailing slash like /folder1/folder2/ -> /folder1/folder2 const formatedQuery = query.map(({ envId, secretPath }) => { - const formatedPath = - secretPath.at(-1) === "/" && secretPath.length > 1 ? secretPath.slice(0, -1) : secretPath; + const formatedPath = secretPath.at(-1) === "/" && secretPath.length > 1 ? secretPath.slice(0, -1) : secretPath; const segments = formatedPath.split("/").filter(Boolean); if (segments.some((segment) => !validateFolderName(segment))) { throw new BadRequestError({ message: "Invalid folder name" }); @@ -73,9 +64,9 @@ const sqlFindMultipleFolderByEnvPathQuery = ( .where((wb) => formatedQuery.map(({ secretPath }) => wb.orWhereRaw( - `depth = array_position(ARRAY[${secretPath - .map(() => "?") - .join(",")}]::varchar[], ${TableName.SecretFolder}.name,depth)`, + `depth = array_position(ARRAY[${secretPath.map(() => "?").join(",")}]::varchar[], ${ + TableName.SecretFolder + }.name,depth)`, [...secretPath] ) ) @@ -92,15 +83,9 @@ const sqlFindMultipleFolderByEnvPathQuery = ( .from("parent"); }; -const sqlFindFolderByPathQuery = ( - db: Knex, - projectId: string, - environment: string, - secretPath: string -) => { +const sqlFindFolderByPathQuery = (db: Knex, projectId: string, environment: string, secretPath: string) => { // this is removing an trailing slash like /folder1/folder2/ -> /folder1/folder2 - const formatedPath = - secretPath.at(-1) === "/" && secretPath.length > 1 ? secretPath.slice(0, -1) : secretPath; + const formatedPath = secretPath.at(-1) === "/" && secretPath.length > 1 ? secretPath.slice(0, -1) : secretPath; // next goal to sanitize saw the raw sql query is safe // for this we ensure folder name contains only string and - nothing else const pathSegments = formatedPath.split("/").filter(Boolean); @@ -121,11 +106,7 @@ const sqlFindFolderByPathQuery = ( path: db.raw("'/'") }) .from(TableName.SecretFolder) - .join( - TableName.Environment, - `${TableName.SecretFolder}.envId`, - `${TableName.Environment}.id` - ) + .join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`) .where({ projectId, parentId: null @@ -156,11 +137,7 @@ const sqlFindFolderByPathQuery = ( ); }) .from("parent") - .leftJoin( - TableName.Environment, - `${TableName.Environment}.id`, - "parent.envId" - ) + .leftJoin(TableName.Environment, `${TableName.Environment}.id`, "parent.envId") .select< TSecretFolders & { depth: number; @@ -192,16 +169,10 @@ const sqlFindSecretPathByFolderId = (db: Knex, projectId: string, folderIds: str // this is for root condition // if the given folder id is root folder id then intial path is set as / instead of /root // if not root folder the path here will be / - path: db.raw( - `CONCAT('/', (CASE WHEN "parentId" is NULL THEN '' ELSE ${TableName.SecretFolder}.name END))` - ), + path: db.raw(`CONCAT('/', (CASE WHEN "parentId" is NULL THEN '' ELSE ${TableName.SecretFolder}.name END))`), child: db.raw("NULL::uuid") }) - .join( - TableName.Environment, - `${TableName.SecretFolder}.envId`, - `${TableName.Environment}.id` - ) + .join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`) .where({ projectId }) .whereIn(`${TableName.SecretFolder}.id`, folderIds) .union( @@ -234,19 +205,9 @@ export const ROOT_FOLDER_NAME = "root"; export const secretFolderDALFactory = (db: TDbClient) => { const secretFolderOrm = ormify(db, TableName.SecretFolder); - const findBySecretPath = async ( - projectId: string, - environment: string, - path: string, - tx?: Knex - ) => { + const findBySecretPath = async (projectId: string, environment: string, path: string, tx?: Knex) => { try { - const folder = await sqlFindFolderByPathQuery( - tx || db, - projectId, - environment, - removeTrailingSlash(path) - ) + const folder = await sqlFindFolderByPathQuery(tx || db, projectId, environment, removeTrailingSlash(path)) .orderBy("depth", "desc") .first(); if (folder && folder.path !== removeTrailingSlash(path)) { @@ -263,19 +224,9 @@ export const secretFolderDALFactory = (db: TDbClient) => { // used in folder creation // even if its the original given /path1/path2 // it will stop automatically at /path2 - const findClosestFolder = async ( - projectId: string, - environment: string, - path: string, - tx?: Knex - ) => { + const findClosestFolder = async (projectId: string, environment: string, path: string, tx?: Knex) => { try { - const folder = await sqlFindFolderByPathQuery( - tx || db, - projectId, - environment, - removeTrailingSlash(path) - ) + const folder = await sqlFindFolderByPathQuery(tx || db, projectId, environment, removeTrailingSlash(path)) .orderBy("depth", "desc") .first(); if (!folder) return; @@ -286,10 +237,7 @@ export const secretFolderDALFactory = (db: TDbClient) => { } }; - const findByManySecretPath = async ( - query: Array<{ envId: string; secretPath: string }>, - tx?: Knex - ) => { + const findByManySecretPath = async (query: Array<{ envId: string; secretPath: string }>, tx?: Knex) => { try { const formatedQuery = query.map(({ secretPath, envId }) => ({ envId, @@ -297,10 +245,7 @@ export const secretFolderDALFactory = (db: TDbClient) => { })); const folders = await sqlFindMultipleFolderByEnvPathQuery(tx || db, formatedQuery); return formatedQuery.map(({ envId, secretPath }) => - folders.find( - ({ path: targetPath, envId: targetEnvId }) => - targetPath === secretPath && targetEnvId === envId - ) + folders.find(({ path: targetPath, envId: targetEnvId }) => targetPath === secretPath && targetEnvId === envId) ); } catch (error) { throw new DatabaseError({ error, name: "FindByManySecretPath" }); @@ -339,11 +284,7 @@ export const secretFolderDALFactory = (db: TDbClient) => { try { const folder = await (tx || db)(TableName.SecretFolder) .where({ [`${TableName.SecretFolder}.id` as "id"]: id }) - .join( - TableName.Environment, - `${TableName.SecretFolder}.envId`, - `${TableName.Environment}.id` - ) + .join(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`) .select(selectAllTableCols(TableName.SecretFolder)) .select( db.ref("id").withSchema(TableName.Environment).as("envId"), diff --git a/backend/src/services/secret-folder/secret-folder-service.ts b/backend/src/services/secret-folder/secret-folder-service.ts index a9e7474c8..082674485 100644 --- a/backend/src/services/secret-folder/secret-folder-service.ts +++ b/backend/src/services/secret-folder/secret-folder-service.ts @@ -4,21 +4,13 @@ import { v4 as uuidv4 } from "uuid"; import { TSecretFoldersInsert } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service"; import { BadRequestError } from "@app/lib/errors"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TSecretFolderDALFactory } from "./secret-folder-dal"; -import { - TCreateFolderDTO, - TDeleteFolderDTO, - TGetFolderDTO, - TUpdateFolderDTO -} from "./secret-folder-types"; +import { TCreateFolderDTO, TDeleteFolderDTO, TGetFolderDTO, TUpdateFolderDTO } from "./secret-folder-types"; import { TSecretFolderVersionDALFactory } from "./secret-folder-version-dal"; type TSecretFolderServiceFactoryDep = { @@ -38,14 +30,7 @@ export const secretFolderServiceFactory = ({ projectEnvDAL, folderVersionDAL }: TSecretFolderServiceFactoryDep) => { - const createFolder = async ({ - projectId, - actor, - actorId, - name, - environment, - path: secretPath - }: TCreateFolderDTO) => { + const createFolder = async ({ projectId, actor, actorId, name, environment, path: secretPath }: TCreateFolderDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, @@ -53,8 +38,7 @@ export const secretFolderServiceFactory = ({ ); const env = await projectEnvDAL.findOne({ projectId, slug: environment }); - if (!env) - throw new BadRequestError({ message: "Environment not found", name: "Create folder" }); + if (!env) throw new BadRequestError({ message: "Environment not found", name: "Create folder" }); const folder = await folderDAL.transaction(async (tx) => { // the logic is simple we need to avoid creating same folder in same path multiple times @@ -62,12 +46,7 @@ export const secretFolderServiceFactory = ({ // so we do a tricky move. we try to find the to be created folder path if that is exactly match return that // else we get some path before that then we will start creating remaining folder const pathWithFolder = path.join(secretPath, name); - const parentFolder = await folderDAL.findClosestFolder( - projectId, - environment, - pathWithFolder, - tx - ); + const parentFolder = await folderDAL.findClosestFolder(projectId, environment, pathWithFolder, tx); // no folder found is not possible root should be their if (!parentFolder) throw new BadRequestError({ message: "Secret path not found" }); // exact folder @@ -78,24 +57,19 @@ export const secretFolderServiceFactory = ({ // this is upsert folder in a path // we are not taking snapshots of this because // snapshot will be removed from automatic for all commits to user click or cron based - const missingSegment = secretPath - .substring(parentFolder.path.length) - .split("/") - .filter(Boolean); + const missingSegment = secretPath.substring(parentFolder.path.length).split("/").filter(Boolean); if (missingSegment.length) { - const newFolders: Array = missingSegment.map( - (segment) => { - const newFolder = { - name: segment, - parentId: parentFolderId, - id: uuidv4(), - envId: env.id, - version: 1 - }; - parentFolderId = newFolder.id; - return newFolder; - } - ); + const newFolders: Array = missingSegment.map((segment) => { + const newFolder = { + name: segment, + parentId: parentFolderId, + id: uuidv4(), + envId: env.id, + version: 1 + }; + parentFolderId = newFolder.id; + return newFolder; + }); parentFolderId = newFolders.at(-1)?.id as string; const docs = await folderDAL.insertMany(newFolders, tx); await folderVersionDAL.insertMany( @@ -110,10 +84,7 @@ export const secretFolderServiceFactory = ({ } } - const doc = await folderDAL.create( - { name, envId: env.id, version: 1, parentId: parentFolderId }, - tx - ); + const doc = await folderDAL.create({ name, envId: env.id, version: 1, parentId: parentFolderId }, tx); await folderVersionDAL.create( { name: doc.name, @@ -149,8 +120,7 @@ export const secretFolderServiceFactory = ({ if (!parentFolder) throw new BadRequestError({ message: "Secret path not found" }); const env = await projectEnvDAL.findOne({ projectId, slug: environment }); - if (!env) - throw new BadRequestError({ message: "Environment not found", name: "Update folder" }); + if (!env) throw new BadRequestError({ message: "Environment not found", name: "Update folder" }); const folder = await folderDAL .findOne({ envId: env.id, id, parentId: parentFolder.id }) // now folder api accepts id based change @@ -160,11 +130,7 @@ export const secretFolderServiceFactory = ({ if (!folder) throw new BadRequestError({ message: "Folder not found" }); const newFolder = await folderDAL.transaction(async (tx) => { - const [doc] = await folderDAL.update( - { envId: env.id, id: folder.id, parentId: parentFolder.id }, - { name }, - tx - ); + const [doc] = await folderDAL.update({ envId: env.id, id: folder.id, parentId: parentFolder.id }, { name }, tx); await folderVersionDAL.create( { name: doc.name, @@ -182,14 +148,7 @@ export const secretFolderServiceFactory = ({ return { folder: newFolder, old: folder }; }; - const deleteFolder = async ({ - projectId, - actor, - actorId, - environment, - path: secretPath, - id - }: TDeleteFolderDTO) => { + const deleteFolder = async ({ projectId, actor, actorId, environment, path: secretPath, id }: TDeleteFolderDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, @@ -197,8 +156,7 @@ export const secretFolderServiceFactory = ({ ); const env = await projectEnvDAL.findOne({ projectId, slug: environment }); - if (!env) - throw new BadRequestError({ message: "Environment not found", name: "Create folder" }); + if (!env) throw new BadRequestError({ message: "Environment not found", name: "Create folder" }); const folder = await folderDAL.transaction(async (tx) => { const parentFolder = await folderDAL.findBySecretPath(projectId, environment, secretPath, tx); @@ -213,13 +171,7 @@ export const secretFolderServiceFactory = ({ return folder; }; - const getFolders = async ({ - projectId, - actor, - actorId, - environment, - path: secretPath - }: TGetFolderDTO) => { + const getFolders = async ({ projectId, actor, actorId, environment, path: secretPath }: TGetFolderDTO) => { // folder list is allowed to be read by anyone // permission to check does user has access await permissionService.getProjectPermission(actor, actorId, projectId); diff --git a/backend/src/services/secret-folder/secret-folder-version-dal.ts b/backend/src/services/secret-folder/secret-folder-version-dal.ts index 138450bb3..f133308cf 100644 --- a/backend/src/services/secret-folder/secret-folder-version-dal.ts +++ b/backend/src/services/secret-folder/secret-folder-version-dal.ts @@ -14,11 +14,7 @@ export const secretFolderVersionDALFactory = (db: TDbClient) => { const findLatestVersionByFolderId = async (folderId: string, tx?: Knex) => { try { const docs = await (tx || db)(TableName.SecretFolderVersion) - .join( - TableName.SecretFolder, - `${TableName.SecretFolderVersion}.folderId`, - `${TableName.SecretFolder}.id` - ) + .join(TableName.SecretFolder, `${TableName.SecretFolderVersion}.folderId`, `${TableName.SecretFolder}.id`) .where({ parentId: folderId }) .join( (tx || db)(TableName.SecretFolderVersion) @@ -42,9 +38,7 @@ export const secretFolderVersionDALFactory = (db: TDbClient) => { const findLatestFolderVersions = async (folderIds: string[], tx?: Knex) => { try { - const docs: Array = await (tx || db)( - TableName.SecretFolderVersion - ) + const docs: Array = await (tx || db)(TableName.SecretFolderVersion) .whereIn("folderId", folderIds) .join( (tx || db)(TableName.SecretFolderVersion) diff --git a/backend/src/services/secret-import/secret-import-dal.ts b/backend/src/services/secret-import/secret-import-dal.ts index 771db02a8..f9c6f1be7 100644 --- a/backend/src/services/secret-import/secret-import-dal.ts +++ b/backend/src/services/secret-import/secret-import-dal.ts @@ -53,11 +53,7 @@ export const secretImportDALFactory = (db: TDbClient) => { try { const docs = await (tx || db)(TableName.SecretImport) .where(filter) - .join( - TableName.Environment, - `${TableName.SecretImport}.importEnv`, - `${TableName.Environment}.id` - ) + .join(TableName.Environment, `${TableName.SecretImport}.importEnv`, `${TableName.Environment}.id`) .select( db.ref("*").withSchema(TableName.SecretImport) as unknown as keyof TSecretImports, db.ref("slug").withSchema(TableName.Environment), diff --git a/backend/src/services/secret-import/secret-import-service.ts b/backend/src/services/secret-import/secret-import-service.ts index b4ba45d01..57142424f 100644 --- a/backend/src/services/secret-import/secret-import-service.ts +++ b/backend/src/services/secret-import/secret-import-service.ts @@ -1,10 +1,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError } from "@app/lib/errors"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; @@ -39,14 +36,7 @@ export const secretImportServiceFactory = ({ folderDAL, secretDAL }: TSecretImportServiceFactoryDep) => { - const createImport = async ({ - environment, - data, - actor, - actorId, - projectId, - path - }: TCreateSecretImportDTO) => { + const createImport = async ({ environment, data, actor, actorId, projectId, path }: TCreateSecretImportDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); // check if user has permission to import into destination path @@ -69,8 +59,7 @@ export const secretImportServiceFactory = ({ // TODO(akhilmhdh-pg): updated permission check add here const [importEnv] = await projectEnvDAL.findBySlugs(projectId, [data.environment]); - if (!importEnv) - throw new BadRequestError({ error: "Imported env not found", name: "Create import" }); + if (!importEnv) throw new BadRequestError({ error: "Imported env not found", name: "Create import" }); const secImport = await secretImportDAL.transaction(async (tx) => { const lastPos = await secretImportDAL.findLastImportPosition(folder.id, tx); @@ -88,15 +77,7 @@ export const secretImportServiceFactory = ({ return { ...secImport, importEnv }; }; - const updateImport = async ({ - path, - environment, - projectId, - actor, - actorId, - data, - id - }: TUpdateSecretImportDTO) => { + const updateImport = async ({ path, environment, projectId, actor, actorId, data, id }: TUpdateSecretImportDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Edit, @@ -112,8 +93,7 @@ export const secretImportServiceFactory = ({ const importedEnv = data.environment // this is get env information of new one or old one ? (await projectEnvDAL.findBySlugs(projectId, [data.environment]))?.[0] : await projectEnvDAL.findById(secImpDoc.importEnv); - if (!importedEnv) - throw new BadRequestError({ error: "Imported env not found", name: "Create import" }); + if (!importedEnv) throw new BadRequestError({ error: "Imported env not found", name: "Create import" }); const updatedSecImport = await secretImportDAL.transaction(async (tx) => { const secImp = await secretImportDAL.findOne({ folderId: folder.id, id }); @@ -135,14 +115,7 @@ export const secretImportServiceFactory = ({ return { ...updatedSecImport, importEnv: importedEnv }; }; - const deleteImport = async ({ - path, - environment, - projectId, - actor, - actorId, - id - }: TDeleteSecretImportDTO) => { + const deleteImport = async ({ path, environment, projectId, actor, actorId, id }: TDeleteSecretImportDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, @@ -154,25 +127,17 @@ export const secretImportServiceFactory = ({ const secImport = await secretImportDAL.transaction(async (tx) => { const [doc] = await secretImportDAL.delete({ folderId: folder.id, id }, tx); - if (!doc) - throw new BadRequestError({ name: "Sec imp del", message: "Secret import doc not found" }); + if (!doc) throw new BadRequestError({ name: "Sec imp del", message: "Secret import doc not found" }); await secretImportDAL.updateAllPosition(folder.id, doc.position, -1, tx); const importEnv = await projectEnvDAL.findById(doc.importEnv); - if (!importEnv) - throw new BadRequestError({ error: "Imported env not found", name: "Create import" }); + if (!importEnv) throw new BadRequestError({ error: "Imported env not found", name: "Create import" }); return { ...doc, importEnv }; }); return secImport; }; - const getImports = async ({ - path, - environment, - projectId, - actor, - actorId - }: TGetSecretImportsDTO) => { + const getImports = async ({ path, environment, projectId, actor, actorId }: TGetSecretImportsDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, @@ -186,13 +151,7 @@ export const secretImportServiceFactory = ({ return secImports; }; - const getSecretsFromImports = async ({ - path, - environment, - projectId, - actor, - actorId - }: TGetSecretsFromImportDTO) => { + const getSecretsFromImports = async ({ path, environment, projectId, actor, actorId }: TGetSecretsFromImportDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, diff --git a/backend/src/services/secret-tag/secret-tag-dal.ts b/backend/src/services/secret-tag/secret-tag-dal.ts index 2e6b38c02..f1ae2424a 100644 --- a/backend/src/services/secret-tag/secret-tag-dal.ts +++ b/backend/src/services/secret-tag/secret-tag-dal.ts @@ -23,11 +23,7 @@ export const secretTagDALFactory = (db: TDbClient) => { const deleteTagsManySecret = async (projectId: string, secretIds: string[], tx?: Knex) => { try { const tags = await (tx || db)(TableName.JnSecretTag) - .join( - TableName.SecretTag, - `${TableName.JnSecretTag}.${TableName.SecretTag}Id`, - `${TableName.SecretTag}.id` - ) + .join(TableName.SecretTag, `${TableName.JnSecretTag}.${TableName.SecretTag}Id`, `${TableName.SecretTag}.id`) .where("projectId", projectId) .whereIn(`${TableName.Secret}Id`, secretIds) .delete() diff --git a/backend/src/services/secret-tag/secret-tag-service.ts b/backend/src/services/secret-tag/secret-tag-service.ts index 8b097e595..060529656 100644 --- a/backend/src/services/secret-tag/secret-tag-service.ts +++ b/backend/src/services/secret-tag/secret-tag-service.ts @@ -1,10 +1,7 @@ import { ForbiddenError } from "@casl/ability"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError } from "@app/lib/errors"; import { TSecretTagDALFactory } from "./secret-tag-dal"; @@ -17,16 +14,10 @@ type TSecretTagServiceFactoryDep = { export type TSecretTagServiceFactory = ReturnType; -export const secretTagServiceFactory = ({ - secretTagDAL, - permissionService -}: TSecretTagServiceFactoryDep) => { +export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSecretTagServiceFactoryDep) => { const createTag = async ({ name, slug, actor, color, actorId, projectId }: TCreateTagDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Tags - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Tags); const existingTag = await secretTagDAL.findOne({ slug }); if (existingTag) throw new BadRequestError({ message: "Tag already exist" }); @@ -45,15 +36,8 @@ export const secretTagServiceFactory = ({ const tag = await secretTagDAL.findById(id); if (!tag) throw new BadRequestError({ message: "Tag doesn't exist" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - tag.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Tags - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, tag.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Tags); const deletedTag = await secretTagDAL.deleteById(tag.id); return deletedTag; @@ -61,10 +45,7 @@ export const secretTagServiceFactory = ({ const getProjectTags = async ({ actor, actorId, projectId }: TListProjectTagsDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Tags - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Tags); const tags = await secretTagDAL.find({ projectId }); return tags; diff --git a/backend/src/services/secret/secret-dal.ts b/backend/src/services/secret/secret-dal.ts index 20520bcf2..44b39a948 100644 --- a/backend/src/services/secret/secret-dal.ts +++ b/backend/src/services/secret/secret-dal.ts @@ -11,17 +11,9 @@ export type TSecretDALFactory = ReturnType; export const secretDALFactory = (db: TDbClient) => { const secretOrm = ormify(db, TableName.Secret); - const update = async ( - filter: Partial, - data: Omit, - tx?: Knex - ) => { + const update = async (filter: Partial, data: Omit, tx?: Knex) => { try { - const sec = await (tx || db)(TableName.Secret) - .where(filter) - .update(data) - .increment("version", 1) - .returning("*"); + const sec = await (tx || db)(TableName.Secret).where(filter).update(data).increment("version", 1).returning("*"); return sec; } catch (error) { throw new DatabaseError({ error, name: "update secret" }); @@ -30,10 +22,7 @@ export const secretDALFactory = (db: TDbClient) => { // the idea is to use postgres specific function // insert with id this will cause a conflict then merge the data - const bulkUpdate = async ( - data: Array<{ filter: Partial; data: TSecretsUpdate }>, - tx?: Knex - ) => { + const bulkUpdate = async (data: Array<{ filter: Partial; data: TSecretsUpdate }>, tx?: Knex) => { try { const secs = await Promise.all( data.map(async ({ filter, data: updateData }) => { @@ -91,16 +80,8 @@ export const secretDALFactory = (db: TDbClient) => { .where((bd) => { void bd.whereNull("userId").orWhere({ userId: userId || null }); }) - .leftJoin( - TableName.JnSecretTag, - `${TableName.Secret}.id`, - `${TableName.JnSecretTag}.${TableName.Secret}Id` - ) - .leftJoin( - TableName.SecretTag, - `${TableName.JnSecretTag}.${TableName.SecretTag}Id`, - `${TableName.SecretTag}.id` - ) + .leftJoin(TableName.JnSecretTag, `${TableName.Secret}.id`, `${TableName.JnSecretTag}.${TableName.Secret}Id`) + .leftJoin(TableName.SecretTag, `${TableName.JnSecretTag}.${TableName.SecretTag}Id`, `${TableName.SecretTag}.id`) .select(selectAllTableCols(TableName.Secret)) .select(db.ref("id").withSchema(TableName.SecretTag).as("tagId")) .select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor")) diff --git a/backend/src/services/secret/secret-fns.ts b/backend/src/services/secret/secret-fns.ts index 9abaa8424..0f6caa248 100644 --- a/backend/src/services/secret/secret-fns.ts +++ b/backend/src/services/secret/secret-fns.ts @@ -8,10 +8,7 @@ import { buildSecretBlindIndexFromName, decryptSymmetric128BitHexKeyUTF8 } from import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretDALFactory } from "./secret-dal"; -export const generateSecretBlindIndexBySalt = async ( - secretName: string, - secretBlindIndexDoc: TSecretBlindIndexes -) => { +export const generateSecretBlindIndexBySalt = async (secretName: string, secretBlindIndexDoc: TSecretBlindIndexes) => { const appCfg = getConfig(); const secretBlindIndex = await buildSecretBlindIndexFromName({ secretName, @@ -32,12 +29,7 @@ type TInterpolateSecretArg = { folderDAL: Pick; }; -export const interpolateSecrets = ({ - projectId, - secretEncKey, - secretDAL, - folderDAL -}: TInterpolateSecretArg) => { +export const interpolateSecrets = ({ projectId, secretEncKey, secretDAL, folderDAL }: TInterpolateSecretArg) => { const fetchSecretsCrossEnv = () => { const fetchCache: Record> = {}; @@ -197,10 +189,7 @@ export const interpolateSecrets = ({ return expandSecrets; }; -export const decryptSecretRaw = ( - secret: TSecrets & { workspace: string; environment: string }, - key: string -) => { +export const decryptSecretRaw = (secret: TSecrets & { workspace: string; environment: string }, key: string) => { const secretKey = decryptSymmetric128BitHexKeyUTF8({ ciphertext: secret.secretKeyCiphertext, iv: secret.secretKeyIV, diff --git a/backend/src/services/secret/secret-queue.ts b/backend/src/services/secret/secret-queue.ts index e633cf431..b797b7caf 100644 --- a/backend/src/services/secret/secret-queue.ts +++ b/backend/src/services/secret/secret-queue.ts @@ -23,11 +23,7 @@ import { TWebhookDALFactory } from "../webhook/webhook-dal"; import { fnTriggerWebhook } from "../webhook/webhook-fns"; import { TSecretDALFactory } from "./secret-dal"; import { interpolateSecrets } from "./secret-fns"; -import { - TCreateSecretReminderDTO, - THandleReminderDTO, - TRemoveSecretReminderDTO -} from "./secret-types"; +import { TCreateSecretReminderDTO, THandleReminderDTO, TRemoveSecretReminderDTO } from "./secret-types"; export type TSecretQueueFactory = ReturnType; @@ -105,20 +101,13 @@ export const secretQueueFactory = ({ QueueJobs.SecretReminder, { // on prod it this will be in days, in development this will be second - every: - appCfg.NODE_ENV === "development" - ? secondsToMillis(dto.repeatDays) - : daysToMillisecond(dto.repeatDays) + every: appCfg.NODE_ENV === "development" ? secondsToMillis(dto.repeatDays) : daysToMillisecond(dto.repeatDays) }, `reminder-${dto.secretId}` ); }; - const addSecretReminder = async ({ - oldSecret, - newSecret, - projectId - }: TCreateSecretReminderDTO) => { + const addSecretReminder = async ({ oldSecret, newSecret, projectId }: TCreateSecretReminderDTO) => { try { const appCfg = getConfig(); @@ -179,8 +168,7 @@ export const secretQueueFactory = ({ if (newSecret.type !== "personal" && secretReminderRepeatDays !== undefined) { if ( - (secretReminderRepeatDays && - oldSecret.secretReminderRepeatDays !== secretReminderRepeatDays) || + (secretReminderRepeatDays && oldSecret.secretReminderRepeatDays !== secretReminderRepeatDays) || (secretReminderNote && oldSecret.secretReminderNote !== secretReminderNote) ) { await addSecretReminder({ @@ -212,10 +200,7 @@ export const secretQueueFactory = ({ secretDAL, folderDAL }); - const content: Record< - string, - { value: string; comment?: string; skipMultilineEncoding?: boolean } - > = {}; + const content: Record = {}; importedSecrets.forEach(({ secrets: secs }) => { secs.forEach((secret) => { @@ -294,8 +279,7 @@ export const secretQueueFactory = ({ const integrations = await integrationDAL.findByProjectIdV2(projectId, environment); const toBeSyncedIntegrations = integrations.filter( - ({ secretPath: integrationSecPath, isActive }) => - isActive && isSamePath(secretPath, integrationSecPath) + ({ secretPath: integrationSecPath, isActive }) => isActive && isSamePath(secretPath, integrationSecPath) ); if (!integrations.length) return; @@ -309,14 +293,8 @@ export const secretQueueFactory = ({ }; const botKey = await projectBotService.getBotKey(projectId); - const { accessToken, accessId } = await integrationAuthService.getIntegrationAccessToken( - integrationAuth, - botKey - ); - const secrets = await getIntegrationSecrets( - { environment, projectId, secretPath, folderId: folder.id }, - botKey - ); + const { accessToken, accessId } = await integrationAuthService.getIntegrationAccessToken(integrationAuth, botKey); + const secrets = await getIntegrationSecrets({ environment, projectId, secretPath, folderId: folder.id }, botKey); const suffixedSecrets: typeof secrets = {}; const metadata = integration.metadata as Record; if (metadata) { @@ -353,25 +331,19 @@ export const secretQueueFactory = ({ const project = await projectDAL.findById(projectId); if (!organization) { - logger.info( - `secretReminderQueue.process: [secretDocument=${data.secretId}] no organization found` - ); + logger.info(`secretReminderQueue.process: [secretDocument=${data.secretId}] no organization found`); return; } if (!project) { - logger.info( - `secretReminderQueue.process: [secretDocument=${data.secretId}] no project found` - ); + logger.info(`secretReminderQueue.process: [secretDocument=${data.secretId}] no project found`); return; } const projectMembers = await projectMembershipDAL.findAllProjectMembers(projectId); if (!projectMembers || !projectMembers.length) { - logger.info( - `secretReminderQueue.process: [secretDocument=${data.secretId}] no project members found` - ); + logger.info(`secretReminderQueue.process: [secretDocument=${data.secretId}] no project members found`); return; } diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index f210a72a2..71086446f 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -1,17 +1,8 @@ import { ForbiddenError, subject } from "@casl/ability"; -import { - SecretEncryptionAlgo, - SecretKeyEncoding, - SecretsSchema, - SecretType, - TableName -} from "@app/db/schemas"; +import { SecretEncryptionAlgo, SecretKeyEncoding, SecretsSchema, SecretType, TableName } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service"; import { getConfig } from "@app/lib/config/env"; import { buildSecretBlindIndexFromName, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto"; @@ -58,17 +49,11 @@ type TSecretServiceFactoryDep = { secretDAL: TSecretDALFactory; secretTagDAL: TSecretTagDALFactory; secretVersionDAL: TSecretVersionDALFactory; - folderDAL: Pick< - TSecretFolderDALFactory, - "findBySecretPath" | "updateById" | "findById" | "findByManySecretPath" - >; + folderDAL: Pick; secretBlindIndexDAL: TSecretBlindIndexDALFactory; permissionService: Pick; snapshotService: Pick; - secretQueueService: Pick< - TSecretQueueFactory, - "syncSecrets" | "handleSecretReminder" | "removeSecretReminder" - >; + secretQueueService: Pick; projectBotService: Pick; secretImportDAL: Pick; secretVersionTagDAL: Pick; @@ -93,8 +78,7 @@ export const secretServiceFactory = ({ const appCfg = getConfig(); const secretBlindIndexDoc = await secretBlindIndexDAL.findOne({ projectId }); - if (!secretBlindIndexDoc) - throw new BadRequestError({ message: "Blind index not found", name: "Create secret" }); + if (!secretBlindIndexDoc) throw new BadRequestError({ message: "Blind index not found", name: "Create secret" }); const secretBlindIndex = await buildSecretBlindIndexFromName({ secretName, @@ -116,15 +100,11 @@ export const secretServiceFactory = ({ inputSecrets.map(({ tags, ...el }) => ({ ...el, folderId })), tx ); - const newSecretGroupByBlindIndex = groupBy( - newSecrets, - (item) => item.secretBlindIndex as string - ); + const newSecretGroupByBlindIndex = groupBy(newSecrets, (item) => item.secretBlindIndex as string); const newSecretTags = inputSecrets.flatMap(({ tags: secretTags = [], secretBlindIndex }) => secretTags.map((tag) => ({ [`${TableName.SecretTag}Id` as const]: tag, - [`${TableName.Secret}Id` as const]: - newSecretGroupByBlindIndex[secretBlindIndex as string][0].id + [`${TableName.Secret}Id` as const]: newSecretGroupByBlindIndex[secretBlindIndex as string][0].id })) ); const secretVersions = await secretVersionDAL.insertMany( @@ -148,12 +128,7 @@ export const secretServiceFactory = ({ return newSecrets.map((secret) => ({ ...secret, _id: secret.id })); }; - const fnSecretBulkUpdate = async ({ - tx, - inputSecrets, - folderId, - projectId - }: TFnSecretBulkUpdate) => { + const fnSecretBulkUpdate = async ({ tx, inputSecrets, folderId, projectId }: TFnSecretBulkUpdate) => { const newSecrets = await secretDAL.bulkUpdate( inputSecrets.map(({ filter, data: { tags, ...data } }) => ({ filter: { ...filter, folderId }, @@ -197,12 +172,7 @@ export const secretServiceFactory = ({ return newSecrets.map((secret) => ({ ...secret, _id: secret.id })); }; - const fnSecretBulkDelete = async ({ - folderId, - inputSecrets, - tx, - actorId - }: TFnSecretBulkDelete) => { + const fnSecretBulkDelete = async ({ folderId, inputSecrets, tx, actorId }: TFnSecretBulkDelete) => { const deletedSecrets = await secretDAL.deleteMany( inputSecrets.map(({ type, secretBlindIndex }) => ({ blindIndex: secretBlindIndex, @@ -245,9 +215,7 @@ export const secretServiceFactory = ({ }: TFnSecretBlindIndexCheck) => { const blindIndex2KeyName: Record = {}; // used at audit log point const keyName2BlindIndex = await Promise.all( - inputSecrets.map(({ secretName }) => - generateSecretBlindIndexBySalt(secretName, blindIndexCfg) - ) + inputSecrets.map(({ secretName }) => generateSecretBlindIndexBySalt(secretName, blindIndexCfg)) ).then((blindIndexes) => blindIndexes.reduce>((prev, curr, i) => { // eslint-disable-next-line @@ -282,11 +250,7 @@ export const secretServiceFactory = ({ // this is used when secret blind index already exist // mainly for secret approval - const fnSecretBlindIndexCheckV2 = async ({ - inputSecrets, - folderId, - userId - }: TFnSecretBlindIndexCheckV2) => { + const fnSecretBlindIndexCheckV2 = async ({ inputSecrets, folderId, userId }: TFnSecretBlindIndexCheckV2) => { if (inputSecrets.some(({ type }) => type === SecretType.Personal) && !userId) { throw new BadRequestError({ message: "Missing user id for personal secret" }); } @@ -303,14 +267,7 @@ export const secretServiceFactory = ({ return { secsGroupedByBlindIndex, secrets }; }; - const createSecret = async ({ - path, - actor, - actorId, - environment, - projectId, - ...inputSecret - }: TCreateSecretDTO) => { + const createSecret = async ({ path, actor, actorId, environment, projectId, ...inputSecret }: TCreateSecretDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, @@ -322,8 +279,7 @@ export const secretServiceFactory = ({ const folderId = folder.id; const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId }); - if (!blindIndexCfg) - throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" }); + if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" }); if (ActorType.USER !== actor && inputSecret.type === SecretType.Personal) { throw new BadRequestError({ message: "Must be user to create personal secret" }); @@ -352,11 +308,8 @@ export const secretServiceFactory = ({ // validate tags // fetch all tags and if not same count throw error meaning one was invalid tags - const tags = inputSecret.tags - ? await secretTagDAL.findManyTagsById(projectId, inputSecret.tags) - : []; - if ((inputSecret.tags || []).length !== tags.length) - throw new BadRequestError({ message: "Tag not found" }); + const tags = inputSecret.tags ? await secretTagDAL.findManyTagsById(projectId, inputSecret.tags) : []; + if ((inputSecret.tags || []).length !== tags.length) throw new BadRequestError({ message: "Tag not found" }); const { secretName, type, ...el } = inputSecret; const secret = await secretDAL.transaction((tx) => @@ -384,14 +337,7 @@ export const secretServiceFactory = ({ return { ...secret[0], environment, workspace: projectId, tags }; }; - const updateSecret = async ({ - path, - actor, - actorId, - environment, - projectId, - ...inputSecret - }: TUpdateSecretDTO) => { + const updateSecret = async ({ path, actor, actorId, environment, projectId, ...inputSecret }: TUpdateSecretDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Edit, @@ -403,8 +349,7 @@ export const secretServiceFactory = ({ const folderId = folder.id; const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId }); - if (!blindIndexCfg) - throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" }); + if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" }); if (ActorType.USER !== actor && inputSecret.type === SecretType.Personal) { throw new BadRequestError({ message: "Must be user to create personal secret" }); @@ -441,11 +386,8 @@ export const secretServiceFactory = ({ projectId }); - const tags = inputSecret.tags - ? await secretTagDAL.findManyTagsById(projectId, inputSecret.tags) - : []; - if ((inputSecret.tags || []).length !== tags.length) - throw new BadRequestError({ message: "Tag not found" }); + const tags = inputSecret.tags ? await secretTagDAL.findManyTagsById(projectId, inputSecret.tags) : []; + if ((inputSecret.tags || []).length !== tags.length) throw new BadRequestError({ message: "Tag not found" }); const { secretName, ...el } = inputSecret; const updatedSecret = await secretDAL.transaction(async (tx) => @@ -487,14 +429,7 @@ export const secretServiceFactory = ({ return { ...updatedSecret[0], workspace: projectId, environment }; }; - const deleteSecret = async ({ - path, - actor, - actorId, - environment, - projectId, - ...inputSecret - }: TDeleteSecretDTO) => { + const deleteSecret = async ({ path, actor, actorId, environment, projectId, ...inputSecret }: TDeleteSecretDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, @@ -506,8 +441,7 @@ export const secretServiceFactory = ({ const folderId = folder.id; const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId }); - if (!blindIndexCfg) - throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" }); + if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" }); if (ActorType.USER !== actor && inputSecret.type === SecretType.Personal) { throw new BadRequestError({ message: "Must be user to create personal secret" }); @@ -542,14 +476,7 @@ export const secretServiceFactory = ({ return { ...deletedSecret[0], _id: deletedSecret[0].id, workspace: projectId, environment }; }; - const getSecrets = async ({ - actorId, - path, - environment, - projectId, - actor, - includeImports - }: TGetSecretsDTO) => { + const getSecrets = async ({ actorId, path, environment, projectId, actor, includeImports }: TGetSecretsDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, @@ -683,8 +610,7 @@ export const secretServiceFactory = ({ const folderId = folder.id; const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId }); - if (!blindIndexCfg) - throw new BadRequestError({ message: "Blind index not found", name: "Update secret" }); + if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" }); const { keyName2BlindIndex } = await fnSecretBlindIndexCheck({ inputSecrets, @@ -738,8 +664,7 @@ export const secretServiceFactory = ({ const folderId = folder.id; const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId }); - if (!blindIndexCfg) - throw new BadRequestError({ message: "Blind index not found", name: "Update secret" }); + if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" }); const { keyName2BlindIndex } = await fnSecretBlindIndexCheck({ inputSecrets, @@ -809,8 +734,7 @@ export const secretServiceFactory = ({ const folderId = folder.id; const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId }); - if (!blindIndexCfg) - throw new BadRequestError({ message: "Blind index not found", name: "Update secret" }); + if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" }); const { keyName2BlindIndex } = await fnSecretBlindIndexCheck({ inputSecrets, @@ -838,46 +762,22 @@ export const secretServiceFactory = ({ return secretsDeleted; }; - const listSecretVersionsBySecretId = async ({ - actorId, - actor, - limit, - offset, - secretId - }: TListSecretVersionDTO) => { + const listSecretVersionsBySecretId = async ({ actorId, actor, limit, offset, secretId }: TListSecretVersionDTO) => { const secret = await secretDAL.findById(secretId); if (!secret) throw new BadRequestError({ message: "Failed to find secret" }); const folder = await folderDAL.findById(secret.folderId); if (!folder) throw new BadRequestError({ message: "Folder not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - folder.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.SecretRollback - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, folder.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); - const secretVersions = await secretVersionDAL.find( - { secretId }, - { limit, offset, sort: [["createdAt", "desc"]] } - ); + const secretVersions = await secretVersionDAL.find({ secretId }, { limit, offset, sort: [["createdAt", "desc"]] }); return secretVersions; }; - const getSecretsRaw = async ({ - projectId, - path, - actor, - actorId, - environment, - includeImports - }: TGetSecretsRawDTO) => { + const getSecretsRaw = async ({ projectId, path, actor, actorId, environment, includeImports }: TGetSecretsRawDTO) => { const botKey = await projectBotService.getBotKey(projectId); - if (!botKey) - throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); + if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); const { secrets, imports } = await getSecrets({ actorId, @@ -911,8 +811,7 @@ export const secretServiceFactory = ({ version }: TGetASecretRawDTO) => { const botKey = await projectBotService.getBotKey(projectId); - if (!botKey) - throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); + if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); const secret = await getSecretByName({ actorId, @@ -941,8 +840,7 @@ export const secretServiceFactory = ({ skipMultilineEncoding }: TCreateSecretRawDTO) => { const botKey = await projectBotService.getBotKey(projectId); - if (!botKey) - throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); + if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretName, botKey); const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey); @@ -986,8 +884,7 @@ export const secretServiceFactory = ({ skipMultilineEncoding }: TUpdateSecretRawDTO) => { const botKey = await projectBotService.getBotKey(projectId); - if (!botKey) - throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); + if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey); @@ -1021,8 +918,7 @@ export const secretServiceFactory = ({ secretPath }: TDeleteSecretRawDTO) => { const botKey = await projectBotService.getBotKey(projectId); - if (!botKey) - throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); + if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); const secret = await deleteSecret({ secretName, @@ -1040,33 +936,17 @@ export const secretServiceFactory = ({ return decryptSecretRaw(secret, botKey); }; - const getSecretVersions = async ({ - actorId, - actor, - limit = 20, - offset = 0, - secretId - }: TGetSecretVersionsDTO) => { + const getSecretVersions = async ({ actorId, actor, limit = 20, offset = 0, secretId }: TGetSecretVersionsDTO) => { const secret = await secretDAL.findById(secretId); if (!secret) throw new BadRequestError({ message: "Failed to find secret" }); const folder = await folderDAL.findById(secret.folderId); if (!folder) throw new BadRequestError({ message: "Failed to find secret" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - folder.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.SecretRollback - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, folder.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); - const secretVersions = await secretVersionDAL.find( - { secretId }, - { offset, limit, sort: [["createdAt", "desc"]] } - ); + const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] }); return secretVersions; }; diff --git a/backend/src/services/secret/secret-types.ts b/backend/src/services/secret/secret-types.ts index f5fdf32a2..89e16d77b 100644 --- a/backend/src/services/secret/secret-types.ts +++ b/backend/src/services/secret/secret-types.ts @@ -1,20 +1,11 @@ import { Knex } from "knex"; -import { - SecretType, - TSecretBlindIndexes, - TSecrets, - TSecretsInsert, - TSecretsUpdate -} from "@app/db/schemas"; +import { SecretType, TSecretBlindIndexes, TSecrets, TSecretsInsert, TSecretsUpdate } from "@app/db/schemas"; import { TProjectPermission } from "@app/lib/types"; type TPartialSecret = Pick; -type TPartialInputSecret = Pick< - TSecrets, - "type" | "secretReminderNote" | "secretReminderRepeatDays" | "id" ->; +type TPartialInputSecret = Pick; export type TCreateSecretDTO = { secretName: string; diff --git a/backend/src/services/secret/secret-version-dal.ts b/backend/src/services/secret/secret-version-dal.ts index 339b8346b..7a6695e18 100644 --- a/backend/src/services/secret/secret-version-dal.ts +++ b/backend/src/services/secret/secret-version-dal.ts @@ -38,17 +38,11 @@ export const secretVersionDALFactory = (db: TDbClient) => { const findLatestVersionMany = async (folderId: string, secretIds: string[], tx?: Knex) => { try { - const docs: Array = await (tx || db)( - TableName.SecretVersion - ) + const docs: Array = await (tx || db)(TableName.SecretVersion) .where("folderId", folderId) .whereIn(`${TableName.SecretVersion}.secretId`, secretIds) .join( - (tx || db)(TableName.SecretVersion) - .groupBy("secretId") - .max("version") - .select("secretId") - .as("latestVersion"), + (tx || db)(TableName.SecretVersion).groupBy("secretId").max("version").select("secretId").as("latestVersion"), (bd) => { bd.on(`${TableName.SecretVersion}.secretId`, "latestVersion.secretId").andOn( `${TableName.SecretVersion}.version`, diff --git a/backend/src/services/service-token/service-token-service.ts b/backend/src/services/service-token/service-token-service.ts index 63d5f6aac..3813d6c05 100644 --- a/backend/src/services/service-token/service-token-service.ts +++ b/backend/src/services/service-token/service-token-service.ts @@ -4,10 +4,7 @@ import { ForbiddenError, subject } from "@casl/ability"; import bcrypt from "bcrypt"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, UnauthorizedError } from "@app/lib/errors"; @@ -50,10 +47,7 @@ export const serviceTokenServiceFactory = ({ encryptedKey }: TCreateServiceTokenDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.ServiceTokens - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.ServiceTokens); scopes.forEach(({ environment, secretPath }) => { ForbiddenError.from(permission).throwUnlessCan( @@ -67,8 +61,7 @@ export const serviceTokenServiceFactory = ({ // validates env const scopeEnvs = [...new Set(scopes.map(({ environment }) => environment))]; const inputEnvs = await projectEnvDAL.findBySlugs(projectId, scopeEnvs); - if (inputEnvs.length !== scopeEnvs.length) - throw new BadRequestError({ message: "Environment not found" }); + if (inputEnvs.length !== scopeEnvs.length) throw new BadRequestError({ message: "Environment not found" }); const secret = crypto.randomBytes(16).toString("hex"); const secretHash = await bcrypt.hash(secret, appCfg.SALT_ROUNDS); @@ -101,23 +94,15 @@ export const serviceTokenServiceFactory = ({ const serviceToken = await serviceTokenDAL.findById(id); if (!serviceToken) throw new BadRequestError({ message: "Token not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - serviceToken.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.ServiceTokens - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, serviceToken.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.ServiceTokens); const deletedServiceToken = await serviceTokenDAL.deleteById(id); return deletedServiceToken; }; const getServiceToken = async ({ actor, actorId }: TGetServiceTokenInfoDTO) => { - if (actor !== ActorType.SERVICE) - throw new BadRequestError({ message: "Service token not found" }); + if (actor !== ActorType.SERVICE) throw new BadRequestError({ message: "Service token not found" }); const serviceToken = await serviceTokenDAL.findById(actorId); if (!serviceToken) throw new BadRequestError({ message: "Token not found" }); @@ -128,16 +113,9 @@ export const serviceTokenServiceFactory = ({ return { serviceToken, user: serviceTokenUser }; }; - const getProjectServiceTokens = async ({ - actorId, - actor, - projectId - }: TProjectServiceTokensDTO) => { + const getProjectServiceTokens = async ({ actorId, actor, projectId }: TProjectServiceTokensDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.ServiceTokens - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.ServiceTokens); const tokens = await serviceTokenDAL.find({ projectId }); return tokens; diff --git a/backend/src/services/super-admin/super-admin-service.ts b/backend/src/services/super-admin/super-admin-service.ts index a549cfac5..c31d55d46 100644 --- a/backend/src/services/super-admin/super-admin-service.ts +++ b/backend/src/services/super-admin/super-admin-service.ts @@ -19,8 +19,7 @@ export type TSuperAdminServiceFactory = ReturnType; export const getServerCfg = () => { - if (!serverCfg) - throw new BadRequestError({ name: "Get server cfg", message: "Server cfg not initialized" }); + if (!serverCfg) throw new BadRequestError({ name: "Get server cfg", message: "Server cfg not initialized" }); return serverCfg; }; @@ -64,8 +63,7 @@ export const superAdminServiceFactory = ({ userAgent }: TAdminSignUpDTO) => { const existingUser = await userDAL.findOne({ email }); - if (existingUser) - throw new BadRequestError({ name: "Admin sign up", message: "User already exist" }); + if (existingUser) throw new BadRequestError({ name: "Admin sign up", message: "User already exist" }); const userInfo = await userDAL.transaction(async (tx) => { const newUser = await userDAL.create( diff --git a/backend/src/services/user/user-dal.ts b/backend/src/services/user/user-dal.ts index 8051cee28..0de490399 100644 --- a/backend/src/services/user/user-dal.ts +++ b/backend/src/services/user/user-dal.ts @@ -24,11 +24,7 @@ export const userDALFactory = (db: TDbClient) => { try { return await db(TableName.Users) .where({ email }) - .join( - TableName.UserEncryptionKey, - `${TableName.Users}.id`, - `${TableName.UserEncryptionKey}.userId` - ) + .join(TableName.UserEncryptionKey, `${TableName.Users}.id`, `${TableName.UserEncryptionKey}.userId`) .first(); } catch (error) { throw new DatabaseError({ error, name: "Find user enc by email" }); @@ -39,11 +35,7 @@ export const userDALFactory = (db: TDbClient) => { try { const user = await db(TableName.Users) .where(`${TableName.Users}.id`, userId) - .join( - TableName.UserEncryptionKey, - `${TableName.Users}.id`, - `${TableName.UserEncryptionKey}.userId` - ) + .join(TableName.UserEncryptionKey, `${TableName.Users}.id`, `${TableName.UserEncryptionKey}.userId`) .first(); if (user?.id) { // change to user id @@ -64,11 +56,7 @@ export const userDALFactory = (db: TDbClient) => { } }; - const updateUserEncryptionByUserId = async ( - userId: string, - data: TUserEncryptionKeysUpdate, - tx?: Knex - ) => { + const updateUserEncryptionByUserId = async (userId: string, data: TUserEncryptionKeysUpdate, tx?: Knex) => { try { const [userEnc] = await (tx || db)(TableName.UserEncryptionKey) .where({ userId }) @@ -86,10 +74,7 @@ export const userDALFactory = (db: TDbClient) => { tx?: Knex ) => { try { - const [userEnc] = await (tx - ? tx(TableName.UserEncryptionKey) - : db(TableName.UserEncryptionKey) - ) + const [userEnc] = await (tx ? tx(TableName.UserEncryptionKey) : db(TableName.UserEncryptionKey)) // if user insert make sure to pass all required data .insert({ userId, ...data } as TUserEncryptionKeys) .onConflict("userId") diff --git a/backend/src/services/user/user-service.ts b/backend/src/services/user/user-service.ts index 81c7ea9d2..b700869c2 100644 --- a/backend/src/services/user/user-service.ts +++ b/backend/src/services/user/user-service.ts @@ -31,9 +31,7 @@ export const userServiceFactory = ({ userDAL }: TUserServiceFactoryDep) => { if (!user) throw new BadRequestError({ name: "Update auth methods" }); const hasSamlEnabled = user?.authMethods?.some((method) => - [AuthMethod.OKTA_SAML, AuthMethod.AZURE_SAML, AuthMethod.JUMPCLOUD_SAML].includes( - method as AuthMethod - ) + [AuthMethod.OKTA_SAML, AuthMethod.AZURE_SAML, AuthMethod.JUMPCLOUD_SAML].includes(method as AuthMethod) ); if (hasSamlEnabled) throw new BadRequestError({ diff --git a/backend/src/services/webhook/webhook-dal.ts b/backend/src/services/webhook/webhook-dal.ts index 9e30c9c35..d1bd2e80a 100644 --- a/backend/src/services/webhook/webhook-dal.ts +++ b/backend/src/services/webhook/webhook-dal.ts @@ -63,12 +63,7 @@ export const webhookDALFactory = (db: TDbClient) => { } }; - const findAllWebhooks = async ( - projectId: string, - environment?: string, - secretPath?: string, - tx?: Knex - ) => { + const findAllWebhooks = async (projectId: string, environment?: string, secretPath?: string, tx?: Knex) => { try { const webhooks = await (tx || db)(TableName.Webhook) .where(`${TableName.Environment}.projectId`, projectId) @@ -103,9 +98,7 @@ export const webhookDALFactory = (db: TDbClient) => { const bulkUpdate = async (data: Array, tx?: Knex) => { try { - const queries = data.map(({ id, ...el }) => - (tx || db)(TableName.Webhook).where({ id }).update(el) - ); + const queries = data.map(({ id, ...el }) => (tx || db)(TableName.Webhook).where({ id }).update(el)); const docs = await Promise.all(queries); return docs; } catch (error) { diff --git a/backend/src/services/webhook/webhook-fns.ts b/backend/src/services/webhook/webhook-fns.ts index e1445acb6..35d2ba7fc 100644 --- a/backend/src/services/webhook/webhook-fns.ts +++ b/backend/src/services/webhook/webhook-fns.ts @@ -44,10 +44,7 @@ export const triggerWebhookRequest = async ( }); } if (secretKey) { - const webhookSign = crypto - .createHmac("sha256", secretKey) - .update(JSON.stringify(payload)) - .digest("hex"); + const webhookSign = crypto.createHmac("sha256", secretKey).update(JSON.stringify(payload)).digest("hex"); headers["x-infisical-signature"] = `t=${payload.timestamp};${webhookSign}`; } } @@ -98,10 +95,7 @@ export const fnTriggerWebhook = async ({ logger.info("Secret webhook job started", { environment, secretPath, projectId }); const webhooksTriggered = await Promise.allSettled( toBeTriggeredHooks.map((hook) => - triggerWebhookRequest( - hook, - getWebhookPayload("secrets.modified", projectId, environment, secretPath) - ) + triggerWebhookRequest(hook, getWebhookPayload("secrets.modified", projectId, environment, secretPath)) ) ); // filter hooks by status diff --git a/backend/src/services/webhook/webhook-service.ts b/backend/src/services/webhook/webhook-service.ts index e176cc865..c208ba472 100644 --- a/backend/src/services/webhook/webhook-service.ts +++ b/backend/src/services/webhook/webhook-service.ts @@ -2,10 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { SecretEncryptionAlgo, SecretKeyEncoding, TWebhooksInsert } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; -import { - ProjectPermissionActions, - ProjectPermissionSub -} from "@app/ee/services/permission/project-permission"; +import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { getConfig } from "@app/lib/config/env"; import { encryptSymmetric, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto"; import { BadRequestError } from "@app/lib/errors"; @@ -29,11 +26,7 @@ type TWebhookServiceFactoryDep = { export type TWebhookServiceFactory = ReturnType; -export const webhookServiceFactory = ({ - webhookDAL, - projectEnvDAL, - permissionService -}: TWebhookServiceFactoryDep) => { +export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionService }: TWebhookServiceFactoryDep) => { const createWebhook = async ({ actor, actorId, @@ -44,10 +37,7 @@ export const webhookServiceFactory = ({ webhookSecretKey }: TCreateWebhookDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Create, - ProjectPermissionSub.Webhooks - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Webhooks); const env = await projectEnvDAL.findOne({ projectId, slug: environment }); if (!env) throw new BadRequestError({ message: "Env not found" }); @@ -69,10 +59,7 @@ export const webhookServiceFactory = ({ insertDoc.algorithm = SecretEncryptionAlgo.AES_256_GCM; insertDoc.keyEncoding = SecretKeyEncoding.BASE64; } else if (encryptionKey) { - const { ciphertext, iv, tag } = encryptSymmetric128BitHexKeyUTF8( - webhookSecretKey, - encryptionKey - ); + const { ciphertext, iv, tag } = encryptSymmetric128BitHexKeyUTF8(webhookSecretKey, encryptionKey); insertDoc.encryptedSecretKey = ciphertext; insertDoc.iv = iv; insertDoc.tag = tag; @@ -89,15 +76,8 @@ export const webhookServiceFactory = ({ const webhook = await webhookDAL.findById(id); if (!webhook) throw new BadRequestError({ message: "Webhook not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - webhook.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Edit, - ProjectPermissionSub.Webhooks - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, webhook.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Webhooks); const updatedWebhook = await webhookDAL.updateById(id, { isDisabled }); return { ...webhook, ...updatedWebhook }; @@ -107,15 +87,8 @@ export const webhookServiceFactory = ({ const webhook = await webhookDAL.findById(id); if (!webhook) throw new BadRequestError({ message: "Webhook not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - webhook.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Delete, - ProjectPermissionSub.Webhooks - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, webhook.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Webhooks); const deletedWebhook = await webhookDAL.deleteById(id); return { ...webhook, ...deletedWebhook }; @@ -125,15 +98,8 @@ export const webhookServiceFactory = ({ const webhook = await webhookDAL.findById(id); if (!webhook) throw new BadRequestError({ message: "Webhook not found" }); - const { permission } = await permissionService.getProjectPermission( - actor, - actorId, - webhook.projectId - ); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Webhooks - ); + const { permission } = await permissionService.getProjectPermission(actor, actorId, webhook.projectId); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); let webhookError: string | undefined; try { @@ -152,18 +118,9 @@ export const webhookServiceFactory = ({ return { ...webhook, ...updatedWebhook }; }; - const listWebhooks = async ({ - actorId, - actor, - projectId, - secretPath, - environment - }: TListWebhookDTO) => { + const listWebhooks = async ({ actorId, actor, projectId, secretPath, environment }: TListWebhookDTO) => { const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); - ForbiddenError.from(permission).throwUnlessCan( - ProjectPermissionActions.Read, - ProjectPermissionSub.Webhooks - ); + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); return webhookDAL.findAllWebhooks(projectId, environment, secretPath); };