import { Request, Response, NextFunction } from 'express'; import { UnauthorizedRequestError } from '../utils/errors'; import { Membership, } from '../models'; import { validateMembership } from '../helpers/membership'; 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, location = 'params' }: { acceptedRoles: string[]; location?: req; }) => { return async ( req: Request, res: Response, next: NextFunction ) => { try { const { membershipId } = req[location]; const membership = await Membership.findById(membershipId); if (!membership) throw new Error('Failed to find target membership'); const userMembership = await Membership.findOne({ workspace: membership.workspace }); if (!userMembership) throw new Error('Failed to validate own membership') const targetMembership = await validateMembership({ userId: req.user._id.toString(), workspaceId: membership.workspace.toString(), acceptedRoles }); req.targetMembership = targetMembership; return next(); } catch (err) { return next(UnauthorizedRequestError({ message: 'Unable to validate workspace membership' })); } } } export default requireMembershipAuth;