From 393cfe895377daaa0aa94e55590b6c2e28e316af Mon Sep 17 00:00:00 2001 From: Tuan Dang Date: Sun, 5 Nov 2023 18:51:25 +0200 Subject: [PATCH] Remove unused middlewares --- backend/src/ee/middleware/index.ts | 5 -- .../middleware/requireSecretSnapshotAuth.ts | 43 ------------ backend/src/middleware/index.ts | 16 ----- backend/src/middleware/requireBotAuth.ts | 27 -------- .../src/middleware/requireIPAllowlistCheck.ts | 55 ---------------- .../src/middleware/requireIntegrationAuth.ts | 37 ----------- .../requireIntegrationAuthorizationAuth.ts | 49 -------------- .../src/middleware/requireMembershipAuth.ts | 38 ----------- .../middleware/requireMembershipOrgAuth.ts | 37 ----------- .../src/middleware/requireOrganizationAuth.ts | 45 ------------- .../middleware/requireServiceTokenDataAuth.ts | 27 -------- backend/src/validation/bot.ts | 41 ------------ backend/src/validation/integration.ts | 65 ------------------- backend/src/validation/membershipOrg.ts | 50 -------------- 14 files changed, 535 deletions(-) delete mode 100644 backend/src/ee/middleware/index.ts delete mode 100644 backend/src/ee/middleware/requireSecretSnapshotAuth.ts delete mode 100644 backend/src/middleware/requireBotAuth.ts delete mode 100644 backend/src/middleware/requireIPAllowlistCheck.ts delete mode 100644 backend/src/middleware/requireIntegrationAuth.ts delete mode 100644 backend/src/middleware/requireIntegrationAuthorizationAuth.ts delete mode 100644 backend/src/middleware/requireMembershipAuth.ts delete mode 100644 backend/src/middleware/requireMembershipOrgAuth.ts delete mode 100644 backend/src/middleware/requireOrganizationAuth.ts delete mode 100644 backend/src/middleware/requireServiceTokenDataAuth.ts diff --git a/backend/src/ee/middleware/index.ts b/backend/src/ee/middleware/index.ts deleted file mode 100644 index 6a9cd2a07..000000000 --- a/backend/src/ee/middleware/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import requireSecretSnapshotAuth from "./requireSecretSnapshotAuth"; - -export { - requireSecretSnapshotAuth, -} \ No newline at end of file diff --git a/backend/src/ee/middleware/requireSecretSnapshotAuth.ts b/backend/src/ee/middleware/requireSecretSnapshotAuth.ts deleted file mode 100644 index 7cc5d1de7..000000000 --- a/backend/src/ee/middleware/requireSecretSnapshotAuth.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { NextFunction, Request, Response } from "express"; -import { SecretSnapshotNotFoundError } from "../../utils/errors"; -import { SecretSnapshot } from "../models"; -import { - validateMembership, -} from "../../helpers/membership"; - -/** - * Validate if user on request has proper membership for secret snapshot - * @param {Object} obj - * @param {String[]} obj.acceptedRoles - accepted workspace roles - * @param {String[]} obj.acceptedStatuses - accepted workspace statuses - * @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing - */ -const requireSecretSnapshotAuth = ({ - acceptedRoles, -}: { - acceptedRoles: Array<"admin" | "member">; -}) => { - return async (req: Request, res: Response, next: NextFunction) => { - const { secretSnapshotId } = req.params; - - const secretSnapshot = await SecretSnapshot.findById(secretSnapshotId); - - if (!secretSnapshot) { - return next(SecretSnapshotNotFoundError({ - message: "Failed to find secret snapshot", - })); - } - - await validateMembership({ - userId: req.user._id, - workspaceId: secretSnapshot.workspace, - acceptedRoles, - }); - - req.secretSnapshot = secretSnapshot as any; - - next(); - } -} - -export default requireSecretSnapshotAuth; \ No newline at end of file diff --git a/backend/src/middleware/index.ts b/backend/src/middleware/index.ts index bd1d1a48e..ded40da81 100644 --- a/backend/src/middleware/index.ts +++ b/backend/src/middleware/index.ts @@ -1,39 +1,23 @@ import requireAuth from "./requireAuth"; import requireMfaAuth from "./requireMfaAuth"; -import requireBotAuth from "./requireBotAuth"; import requireSignupAuth from "./requireSignupAuth"; import requireWorkspaceAuth from "./requireWorkspaceAuth"; -import requireMembershipAuth from "./requireMembershipAuth"; -import requireMembershipOrgAuth from "./requireMembershipOrgAuth"; -import requireOrganizationAuth from "./requireOrganizationAuth"; -import requireIntegrationAuth from "./requireIntegrationAuth"; -import requireIntegrationAuthorizationAuth from "./requireIntegrationAuthorizationAuth"; import requireServiceTokenAuth from "./requireServiceTokenAuth"; -import requireServiceTokenDataAuth from "./requireServiceTokenDataAuth"; import requireSecretAuth from "./requireSecretAuth"; import requireSecretsAuth from "./requireSecretsAuth"; import requireBlindIndicesEnabled from "./requireBlindIndicesEnabled"; import requireE2EEOff from "./requireE2EEOff"; -import requireIPAllowlistCheck from "./requireIPAllowlistCheck"; import validateRequest from "./validateRequest"; export { requireAuth, requireMfaAuth, - requireBotAuth, requireSignupAuth, requireWorkspaceAuth, - requireMembershipAuth, - requireMembershipOrgAuth, - requireOrganizationAuth, - requireIntegrationAuth, - requireIntegrationAuthorizationAuth, requireServiceTokenAuth, - requireServiceTokenDataAuth, requireSecretAuth, requireSecretsAuth, requireBlindIndicesEnabled, requireE2EEOff, - requireIPAllowlistCheck, validateRequest, }; diff --git a/backend/src/middleware/requireBotAuth.ts b/backend/src/middleware/requireBotAuth.ts deleted file mode 100644 index b0dc36956..000000000 --- a/backend/src/middleware/requireBotAuth.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { NextFunction, Request, Response } from "express"; -import { Types } from "mongoose"; -import { validateClientForBot } from "../validation"; - -type req = "params" | "body" | "query"; - -const requireBotAuth = ({ - acceptedRoles, - locationBotId = "params", -}: { - acceptedRoles: Array<"admin" | "member">; - locationBotId?: req; -}) => { - return async (req: Request, res: Response, next: NextFunction) => { - const { botId } = req[locationBotId]; - - req.bot = await validateClientForBot({ - authData: req.authData, - botId: new Types.ObjectId(botId), - acceptedRoles, - }); - - next(); - } -} - -export default requireBotAuth; \ No newline at end of file diff --git a/backend/src/middleware/requireIPAllowlistCheck.ts b/backend/src/middleware/requireIPAllowlistCheck.ts deleted file mode 100644 index 411c802a9..000000000 --- a/backend/src/middleware/requireIPAllowlistCheck.ts +++ /dev/null @@ -1,55 +0,0 @@ -import net from "net"; -import { NextFunction, Request, Response } from "express"; -import { UnauthorizedRequestError } from "../utils/errors"; -import { extractIPDetails } from "../utils/ip"; -import { ActorType, TrustedIP } from "../ee/models"; - -type req = "params" | "body" | "query"; - -/** - * Validate if workspace with [workspaceId] has E2EE off/disabled - * @param {Object} obj - * @param {String} obj.locationWorkspaceId - location of [workspaceId] on request (e.g. params, body) for parsing - * @returns - */ -const requireIPAllowlistCheck = ({ - locationWorkspaceId -}: { - locationWorkspaceId: req; -}) => { - return async (req: Request, _: Response, next: NextFunction) => { - const workspaceId = req[locationWorkspaceId]?.workspaceId; - - if (req.authData.actor.type === ActorType.SERVICE) { - const trustedIps = await TrustedIP.find({ - workspace: workspaceId - }); - - if (trustedIps.length > 0) { - // case: check the IP address of the inbound request against trusted IPs - - const blockList = new net.BlockList(); - - for (const trustedIp of trustedIps) { - if (trustedIp.prefix !== undefined) { - blockList.addSubnet(trustedIp.ipAddress, trustedIp.prefix, trustedIp.type); - } else { - blockList.addAddress(trustedIp.ipAddress, trustedIp.type); - } - } - - const { type } = extractIPDetails(req.authData.ipAddress); - const check = blockList.check(req.authData.ipAddress, type); - - if (!check) - throw UnauthorizedRequestError({ - message: "Failed workspace authorization" - }); - } - } - - return next(); - } -} - -export default requireIPAllowlistCheck; \ No newline at end of file diff --git a/backend/src/middleware/requireIntegrationAuth.ts b/backend/src/middleware/requireIntegrationAuth.ts deleted file mode 100644 index 5adc04353..000000000 --- a/backend/src/middleware/requireIntegrationAuth.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { NextFunction, Request, Response } from "express"; -import { Types } from "mongoose"; -import { validateClientForIntegration } from "../validation"; - -/** - * Validate if user on request is a member of workspace with proper roles associated - * with the integration on request params. - * @param {Object} obj - * @param {String[]} obj.acceptedRoles - accepted workspace roles - */ -const requireIntegrationAuth = ({ - acceptedRoles, -}: { - acceptedRoles: Array<"admin" | "member">; -}) => { - return async (req: Request, res: Response, next: NextFunction) => { - const { integrationId } = req.params; - - const { integration, accessToken } = await validateClientForIntegration({ - authData: req.authData, - integrationId: new Types.ObjectId(integrationId), - acceptedRoles, - }); - - if (integration) { - req.integration = integration; - } - - if (accessToken) { - req.accessToken = accessToken; - } - - return next(); - }; -}; - -export default requireIntegrationAuth; diff --git a/backend/src/middleware/requireIntegrationAuthorizationAuth.ts b/backend/src/middleware/requireIntegrationAuthorizationAuth.ts deleted file mode 100644 index ccbe7e8a3..000000000 --- a/backend/src/middleware/requireIntegrationAuthorizationAuth.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Types } from "mongoose"; -import { NextFunction, Request, Response } from "express"; -import { validateClientForIntegrationAuth } from "../validation"; - -type req = "params" | "body" | "query"; - -/** - * Validate if user on request is a member of workspace with proper roles associated - * with the integration authorization on request params. - * @param {Object} obj - * @param {String[]} obj.acceptedRoles - accepted workspace roles - * @param {Boolean} obj.attachAccessToken - whether or not to decrypt and attach integration authorization access token onto request - */ -const requireIntegrationAuthorizationAuth = ({ - acceptedRoles, - attachAccessToken = true, - location = "params", -}: { - acceptedRoles: Array<"admin" | "member">; - attachAccessToken?: boolean; - location?: req; -}) => { - return async (req: Request, res: Response, next: NextFunction) => { - const { integrationAuthId } = req[location]; - - const { integrationAuth, accessToken, accessId } = await validateClientForIntegrationAuth({ - authData: req.authData, - integrationAuthId: new Types.ObjectId(integrationAuthId), - acceptedRoles, - attachAccessToken, - }); - - if (integrationAuth) { - req.integrationAuth = integrationAuth; - } - - if (accessToken) { - req.accessToken = accessToken; - } - - if (accessId) { - req.accessId = accessId; - } - - return next(); - }; -}; - -export default requireIntegrationAuthorizationAuth; diff --git a/backend/src/middleware/requireMembershipAuth.ts b/backend/src/middleware/requireMembershipAuth.ts deleted file mode 100644 index cc781677b..000000000 --- a/backend/src/middleware/requireMembershipAuth.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Types } from "mongoose"; -import { NextFunction, Request, Response } from "express"; -import { validateClientForMembership } from "../validation"; - -type req = "params" | "body" | "query"; - -/** - * Validate membership with id [membershipId] and that user with id - * [req.user._id] can modify that membership. - * @param {Object} obj - * @param {String[]} obj.acceptedRoles - accepted workspace roles - * @param {String[]} obj.location - location of [workspaceId] on request (e.g. params, body) for parsing - */ -const requireMembershipAuth = ({ - acceptedRoles, - locationMembershipId = "params", -}: { - acceptedRoles: Array<"admin" | "member">; - locationMembershipId: req -}) => { - return async ( - req: Request, - res: Response, - next: NextFunction - ) => { - const { membershipId } = req[locationMembershipId]; - - req.targetMembership = await validateClientForMembership({ - authData: req.authData, - membershipId: new Types.ObjectId(membershipId), - acceptedRoles, - }); - - return next(); - } -} - -export default requireMembershipAuth; \ No newline at end of file diff --git a/backend/src/middleware/requireMembershipOrgAuth.ts b/backend/src/middleware/requireMembershipOrgAuth.ts deleted file mode 100644 index 00bcb6de8..000000000 --- a/backend/src/middleware/requireMembershipOrgAuth.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Types } from "mongoose"; -import { NextFunction, Request, Response } from "express"; -import { validateClientForMembershipOrg } from "../validation"; - -type req = "params" | "body" | "query"; - -/** - * Validate (organization) membership id [membershipId] and that user with id - * [req.user._id] can modify that membership. - * @param {Object} obj - * @param {String[]} obj.acceptedRoles - accepted organization roles - * @param {String[]} obj.location - location of [membershipId] on request (e.g. params, body) for parsing - */ -const requireMembershipOrgAuth = ({ - acceptedRoles, - acceptedStatuses, - locationMembershipOrgId = "params", -}: { - acceptedRoles: Array<"owner" | "admin" | "member">; - acceptedStatuses: Array<"invited" | "accepted">; - locationMembershipOrgId?: req; -}) => { - return async (req: Request, res: Response, next: NextFunction) => { - const { membershipId } = req[locationMembershipOrgId]; - - req.membershipOrg = await validateClientForMembershipOrg({ - authData: req.authData, - membershipOrgId: new Types.ObjectId(membershipId), - acceptedRoles, - acceptedStatuses, - }); - - return next(); - } -} - -export default requireMembershipOrgAuth; \ No newline at end of file diff --git a/backend/src/middleware/requireOrganizationAuth.ts b/backend/src/middleware/requireOrganizationAuth.ts deleted file mode 100644 index f28660d0e..000000000 --- a/backend/src/middleware/requireOrganizationAuth.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { NextFunction, Request, Response } from "express"; -import { Types } from "mongoose"; -import { validateClientForOrganization } from "../validation"; - -type req = "params" | "body" | "query"; - -/** - * Validate if user on request is a member with proper roles for organization - * on request params. - * @param {Object} obj - * @param {String[]} obj.acceptedRoles - accepted organization roles - * @param {String[]} obj.accepteStatuses - accepted organization statuses - */ -const requireOrganizationAuth = ({ - acceptedRoles, - acceptedStatuses, - locationOrganizationId = "params", -}: { - acceptedRoles: Array<"owner" | "admin" | "member">; - acceptedStatuses: Array<"invited" | "accepted">; - locationOrganizationId?: req; -}) => { - return async (req: Request, res: Response, next: NextFunction) => { - const { organizationId } = req[locationOrganizationId]; - - const { organization, membershipOrg } = await validateClientForOrganization({ - authData: req.authData, - organizationId: new Types.ObjectId(organizationId), - acceptedRoles, - acceptedStatuses, - }); - - if (organization) { - req.organization = organization; - } - - if (membershipOrg) { - req.membershipOrg = membershipOrg; - } - - return next(); - }; -}; - -export default requireOrganizationAuth; diff --git a/backend/src/middleware/requireServiceTokenDataAuth.ts b/backend/src/middleware/requireServiceTokenDataAuth.ts deleted file mode 100644 index df5ca5ef1..000000000 --- a/backend/src/middleware/requireServiceTokenDataAuth.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { NextFunction, Request, Response } from "express"; -import { Types } from "mongoose"; -import { validateClientForServiceTokenData } from "../validation"; - -type req = "params" | "body" | "query"; - -const requireServiceTokenDataAuth = ({ - acceptedRoles, - location = "params", -}: { - acceptedRoles: Array<"admin" | "member">; - location?: req; -}) => { - return async (req: Request, res: Response, next: NextFunction) => { - const { serviceTokenDataId } = req[location]; - - req.serviceTokenData = await validateClientForServiceTokenData({ - authData: req.authData, - serviceTokenDataId: new Types.ObjectId(serviceTokenDataId), - acceptedRoles, - }); - - next(); - } -} - -export default requireServiceTokenDataAuth; \ No newline at end of file diff --git a/backend/src/validation/bot.ts b/backend/src/validation/bot.ts index 2980aeac1..a5fa5b52f 100644 --- a/backend/src/validation/bot.ts +++ b/backend/src/validation/bot.ts @@ -1,46 +1,5 @@ -import { Types } from "mongoose"; -import { Bot, IUser } from "../models"; -import { validateUserClientForWorkspace } from "./user"; -import { BotNotFoundError, UnauthorizedRequestError } from "../utils/errors"; -import { AuthData } from "../interfaces/middleware"; -import { ActorType } from "../ee/models"; import { z } from "zod"; -/** - * Validate authenticated clients for bot with id [botId] based - * on any known permissions. - * @param {Object} obj - * @param {Object} obj.authData - authenticated client details - * @param {Types.ObjectId} obj.botId - id of bot to validate against - * @param {Array<'admin' | 'member'>} obj.acceptedRoles - accepted workspace roles - */ -export const validateClientForBot = async ({ - authData, - botId, - acceptedRoles -}: { - authData: AuthData; - botId: Types.ObjectId; - acceptedRoles: Array<"admin" | "member">; -}) => { - const bot = await Bot.findById(botId); - if (!bot) throw BotNotFoundError(); - - switch (authData.actor.type) { - case ActorType.USER: - await validateUserClientForWorkspace({ - user: authData.authPayload as IUser, - workspaceId: bot.workspace, - acceptedRoles - }); - return bot; - case ActorType.SERVICE: - throw UnauthorizedRequestError({ - message: "Failed service token authorization for bot" - }); - } -}; - export const GetBotByWorkspaceIdV1 = z.object({ params: z.object({ workspaceId: z.string().trim() diff --git a/backend/src/validation/integration.ts b/backend/src/validation/integration.ts index 98dadb924..b5a02b164 100644 --- a/backend/src/validation/integration.ts +++ b/backend/src/validation/integration.ts @@ -1,70 +1,5 @@ -import { Types } from "mongoose"; -import { IUser, Integration, IntegrationAuth } from "../models"; -import { validateUserClientForWorkspace } from "./user"; -import { IntegrationService } from "../services"; -import { - IntegrationAuthNotFoundError, - IntegrationNotFoundError, - UnauthorizedRequestError -} from "../utils/errors"; -import { AuthData } from "../interfaces/middleware"; -import { ActorType } from "../ee/models"; import { z } from "zod"; -/** - * Validate authenticated clients for integration with id [integrationId] based - * on any known permissions. - * @param {Object} obj - * @param {Object} obj.authData - authenticated client details - * @param {Types.ObjectId} obj.integrationId - id of integration to validate against - * @param {String} obj.environment - (optional) environment in workspace to validate against - * @param {Array<'admin' | 'member'>} obj.acceptedRoles - accepted workspace roles - * @param {String[]} obj.requiredPermissions - required permissions as part of the endpoint - */ -export const validateClientForIntegration = async ({ - authData, - integrationId, - acceptedRoles -}: { - authData: AuthData; - integrationId: Types.ObjectId; - acceptedRoles: Array<"admin" | "member">; -}) => { - const integration = await Integration.findById(integrationId); - if (!integration) throw IntegrationNotFoundError(); - - const integrationAuth = await IntegrationAuth.findById(integration.integrationAuth).select( - "+refreshCiphertext +refreshIV +refreshTag +accessCiphertext +accessIV +accessTag +accessExpiresAt metadata" - ); - - if (!integrationAuth) throw IntegrationAuthNotFoundError(); - - const accessToken = ( - await IntegrationService.getIntegrationAuthAccess({ - integrationAuthId: integrationAuth._id - }) - ).accessToken; - - switch (authData.actor.type) { - case ActorType.USER: - await validateUserClientForWorkspace({ - user: authData.authPayload as IUser, - workspaceId: integration.workspace, - acceptedRoles - }); - - return { integration, accessToken }; - case ActorType.SERVICE: - throw UnauthorizedRequestError({ - message: "Failed service token authorization for integration" - }); - case ActorType.SERVICE_V3: - throw UnauthorizedRequestError({ - message: "Failed service token authorization for integration" - }); - } -}; - export const CreateIntegrationV1 = z.object({ body: z.object({ integrationAuthId: z.string().trim(), diff --git a/backend/src/validation/membershipOrg.ts b/backend/src/validation/membershipOrg.ts index 02f9cac08..4656d42fe 100644 --- a/backend/src/validation/membershipOrg.ts +++ b/backend/src/validation/membershipOrg.ts @@ -1,55 +1,5 @@ -import { Types } from "mongoose"; -import { MembershipOrg } from "../models"; -import { validateMembershipOrg } from "../helpers/membershipOrg"; -import { MembershipOrgNotFoundError, UnauthorizedRequestError } from "../utils/errors"; -import { AuthData } from "../interfaces/middleware"; -import { ActorType } from "../ee/models"; import { z } from "zod"; -/** - * Validate authenticated clients for organization membership with id [membershipOrgId] based - * on any known permissions. - * @param {Object} obj - * @param {Object} obj.authData - authenticated client details - * @param {Types.ObjectId} obj.membershipOrgId - id of organization membership to validate against - * @param {Array<'owner' | 'admin' | 'member'>} obj.acceptedRoles - accepted organization roles - * @param {MembershipOrg} - validated organization membership - */ -export const validateClientForMembershipOrg = async ({ - authData, - membershipOrgId, - acceptedRoles, - acceptedStatuses -}: { - authData: AuthData; - membershipOrgId: Types.ObjectId; - acceptedRoles: Array<"owner" | "admin" | "member">; - acceptedStatuses: Array<"invited" | "accepted">; -}) => { - const membershipOrg = await MembershipOrg.findById(membershipOrgId); - - if (!membershipOrg) - throw MembershipOrgNotFoundError({ - message: "Failed to find organization membership " - }); - - switch (authData.actor.type) { - case ActorType.USER: - await validateMembershipOrg({ - userId: authData.authPayload._id, - organizationId: membershipOrg.organization, - acceptedRoles, - acceptedStatuses - }); - - return membershipOrg; - case ActorType.SERVICE: - throw UnauthorizedRequestError({ - message: "Failed service account client authorization for organization membership" - }); - } -}; - export const DelOrgMembershipv1 = z.object({ params: z.object({ membershipOrgId: z.string().trim()