diff --git a/backend/package-lock.json b/backend/package-lock.json index 262d974a7..c0a274770 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -43,6 +43,7 @@ "jsrp": "^0.2.4", "libsodium-wrappers": "^0.7.10", "lodash": "^4.17.21", + "mongodb": "^5.7.0", "mongoose": "^7.4.1", "nanoid": "^3.3.6", "node-cache": "^5.1.2", diff --git a/backend/package.json b/backend/package.json index 8e379bd37..cd38aa20f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -34,6 +34,7 @@ "jsrp": "^0.2.4", "libsodium-wrappers": "^0.7.10", "lodash": "^4.17.21", + "mongodb": "^5.7.0", "mongoose": "^7.4.1", "nanoid": "^3.3.6", "node-cache": "^5.1.2", diff --git a/backend/src/controllers/v1/integrationAuthController.ts b/backend/src/controllers/v1/integrationAuthController.ts index 70410ce35..06b245659 100644 --- a/backend/src/controllers/v1/integrationAuthController.ts +++ b/backend/src/controllers/v1/integrationAuthController.ts @@ -28,6 +28,7 @@ import { } from "../../ee/services/ProjectRoleService"; import { ForbiddenError } from "@casl/ability"; import { getIntegrationAuthAccessHelper } from "../../helpers"; +import { ObjectId } from "mongodb"; /*** * Return integration authorization with id [integrationAuthId] @@ -221,7 +222,7 @@ export const getIntegrationAuthApps = async (req: Request, res: Response) => { // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken, accessId } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -259,7 +260,7 @@ export const getIntegrationAuthTeams = async (req: Request, res: Response) => { // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -295,7 +296,7 @@ export const getIntegrationAuthVercelBranches = async (req: Request, res: Respon // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -356,7 +357,7 @@ export const getIntegrationAuthQoveryOrgs = async (req: Request, res: Response) // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -408,7 +409,7 @@ export const getIntegrationAuthQoveryProjects = async (req: Request, res: Respon // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -469,7 +470,7 @@ export const getIntegrationAuthQoveryEnvironments = async (req: Request, res: Re // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -530,7 +531,7 @@ export const getIntegrationAuthQoveryApps = async (req: Request, res: Response) // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -591,7 +592,7 @@ export const getIntegrationAuthQoveryContainers = async (req: Request, res: Resp // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -652,7 +653,7 @@ export const getIntegrationAuthQoveryJobs = async (req: Request, res: Response) // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -714,7 +715,7 @@ export const getIntegrationAuthRailwayEnvironments = async (req: Request, res: R // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -807,7 +808,7 @@ export const getIntegrationAuthRailwayServices = async (req: Request, res: Respo // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -931,7 +932,7 @@ export const getIntegrationAuthBitBucketWorkspaces = async (req: Request, res: R // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -987,7 +988,7 @@ export const getIntegrationAuthNorthflankSecretGroups = async (req: Request, res // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -1075,7 +1076,7 @@ export const getIntegrationAuthTeamCityBuildConfigs = async (req: Request, res: // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( @@ -1144,7 +1145,7 @@ export const deleteIntegrationAuth = async (req: Request, res: Response) => { // TODO(akhilmhdh): remove class -> static function path and makes these into reusable independent functions const { integrationAuth, accessToken } = await getIntegrationAuthAccessHelper({ - integrationAuthId: new Types.ObjectId(integrationAuthId) + integrationAuthId: new ObjectId(integrationAuthId) }); const { permission } = await getUserProjectPermissions( diff --git a/backend/src/controllers/v2/secretController.ts b/backend/src/controllers/v2/secretController.ts index 28fab01a4..bd36d6ab4 100644 --- a/backend/src/controllers/v2/secretController.ts +++ b/backend/src/controllers/v2/secretController.ts @@ -11,6 +11,7 @@ import { ValidationError as RouteValidationError, UnauthorizedRequestError } from "../../utils/errors"; +import { AnyBulkWriteOperation } from "mongodb"; import { ALGORITHM_AES_256_GCM, ENCODING_SCHEME_UTF8, @@ -18,7 +19,7 @@ import { SECRET_SHARED } from "../../variables"; import { TelemetryService } from "../../services"; -import { Secret, User } from "../../models"; +import { ISecret, Secret, User } from "../../models"; import { AccountNotFoundError } from "../../utils/errors"; /** @@ -144,22 +145,22 @@ export const deleteSecrets = async (req: Request, res: Response) => { const secretsUserCanDeleteSet: Set = new Set( secretIdsUserCanDelete.map((objectId) => objectId._id.toString()) ); + const deleteOperationsToPerform: AnyBulkWriteOperation[] = []; - // Filter out IDs that user can delete and then map them to delete operations - const deleteOperationsToPerform = secretIdsToDelete - .filter(secretIdToDelete => { - if (!secretsUserCanDeleteSet.has(secretIdToDelete)) { - throw RouteValidationError({ - message: "You cannot delete secrets that you do not have access to" - }); - } - return true; - }) - .map(secretIdToDelete => ({ - deleteOne: { filter: { _id: new Types.ObjectId(secretIdToDelete) } } - })); - - const numSecretsDeleted = deleteOperationsToPerform.length; + let numSecretsDeleted = 0; + secretIdsToDelete.forEach((secretIdToDelete) => { + if (secretsUserCanDeleteSet.has(secretIdToDelete)) { + const deleteOperation = { + deleteOne: { filter: { _id: new Types.ObjectId(secretIdToDelete) } } + }; + deleteOperationsToPerform.push(deleteOperation); + numSecretsDeleted++; + } else { + throw RouteValidationError({ + message: "You cannot delete secrets that you do not have access to" + }); + } + }); await Secret.bulkWrite(deleteOperationsToPerform);