get approvals by requester & improve create request

This commit is contained in:
Maidul Islam
2023-02-22 01:03:00 -05:00
parent eb055e8b16
commit 4749e243bb
3 changed files with 40 additions and 21 deletions

View File

@ -1,11 +1,12 @@
import { Request, Response } from 'express';
import SecretApprovalRequest, { ApprovalStatus, IRequestedChange } from '../../models/secretApprovalRequest';
import SecretApprovalRequest, { ApprovalStatus, ChangeType, IApprover, IRequestedChange } from '../../models/secretApprovalRequest';
import { Builder, IBuilder } from "builder-pattern"
import { validateSecrets } from '../../helpers/secret';
import _ from 'lodash';
import { SECRET_PERSONAL, SECRET_SHARED } from '../../variables';
import { BadRequestError, ResourceNotFound } from '../../utils/errors';
import { Workspace } from '../../models';
import { Secret, Workspace } from '../../models';
import { user } from '../../routes/v1';
export const createApprovalRequest = async (req: Request, res: Response) => {
const { workspaceId, environment, requestedChanges } = req.body;
@ -32,24 +33,31 @@ export const createApprovalRequest = async (req: Request, res: Response) => {
throw BadRequestError({ message: "There are no designated approvers for this project, you must set approvers first before making a request" })
}
const approverIds = _.map(workspaceFromDB.approvers, "userId")
const approverIds = _.compact(_.map(workspaceFromDB.approvers, "userId"))
const approversFormatted: IApprover[] = approverIds.map(id => {
return { "userId": id, status: ApprovalStatus.PENDING }
})
const listOfSecretIdsToModify = _.map(requestedChanges, "modifiedSecretId")
const listOfSecretIdsToModify = _.compact(_.map(requestedChanges, "modifiedSecretId"))
// ensure the secrets user is requesting to modify are the ones they have access to
await validateSecrets({
userId: req.user._id.toString(),
secretIds: listOfSecretIdsToModify
});
if (listOfSecretIdsToModify.length > 0) {
await validateSecrets({
userId: req.user._id.toString(),
secretIds: listOfSecretIdsToModify
});
}
const sanitizedRequestedChangesList: IRequestedChange[] = []
requestedChanges.forEach((requestedChange: IRequestedChange) => {
const modifiedSecret = requestedChange.modifiedSecret
if (!modifiedSecret.type || !(modifiedSecret.type === SECRET_PERSONAL || modifiedSecret.type === SECRET_SHARED) || !modifiedSecret.secretKeyCiphertext || !modifiedSecret.secretKeyIV || !modifiedSecret.secretKeyTag || (typeof modifiedSecret.secretValueCiphertext !== 'string') || !modifiedSecret.secretValueIV || !modifiedSecret.secretValueTag) {
throw BadRequestError({ message: "One or more required fields are missing from your modified secret" })
}
if (!requestedChange.modifiedSecretId && (requestedChange.type != ChangeType.DELETE.toString() || requestedChange.type != ChangeType.CREATE.toString())) {
throw BadRequestError({ message: "modifiedSecretId can only be empty when secret change type is DELETE or CREATE" })
}
sanitizedRequestedChangesList.push(Builder<IRequestedChange>()
.modifiedSecretId(requestedChange.modifiedSecretId)
.modifiedSecret(requestedChange.modifiedSecret)
@ -57,6 +65,7 @@ export const createApprovalRequest = async (req: Request, res: Response) => {
});
const filter = {
workspace: workspaceId,
requestedByUserId: req.user._id.toString(),
@ -64,9 +73,10 @@ export const createApprovalRequest = async (req: Request, res: Response) => {
status: ApprovalStatus.PENDING.toString()
};
const update = {
requestedChanges: sanitizedRequestedChangesList,
approvers: approverIds
approvers: approversFormatted
};
const options = {
@ -79,6 +89,15 @@ export const createApprovalRequest = async (req: Request, res: Response) => {
return res.status(200).send(request);
};
export const getAllApprovalRequestsForUser = async (req: Request, res: Response) => {
const approvalRequests = await SecretApprovalRequest.find({
requestedByUserId: req.user._id.toString()
}).populate(["requestedChanges.modifiedSecretId", { path: 'approvers.userId', select: 'firstName lastName _id' }])
.sort({ updatedAt: -1 })
res.send(approvalRequests)
}
export const cancelApprovalRequest = async (req: Request, res: Response) => {
return res.status(200).send({
user: req.user

View File

@ -22,7 +22,7 @@ interface ISecretApprovalRequest {
requestId: string;
}
interface IApprover {
export interface IApprover {
userId: mongoose.Types.ObjectId;
status: ApprovalStatus;
}
@ -40,7 +40,7 @@ export enum ChangeType {
}
const approverSchema = new mongoose.Schema({
user: {
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: false
@ -65,7 +65,7 @@ const secretApprovalRequestSchema = new Schema<ISecretApprovalRequest>(
requestedChanges: [
{
modifiedSecret: secretSchema,
modifiedSecretId: {
modifiedSecretId: { // used to fetch the current version of this secret for comparing
type: mongoose.Schema.Types.ObjectId,
ref: 'Secret'
},

View File

@ -16,13 +16,13 @@ router.post(
secretApprovalController.createApprovalRequest
);
// router.post(
// '/add-approver',
// requireAuth({
// acceptedAuthModes: ['jwt']
// }),
// secretApprovalController.createApprovalRequest
// );
router.get(
'/',
requireAuth({
acceptedAuthModes: ['jwt']
}),
secretApprovalController.getAllApprovalRequestsForUser
);
// router.post(
// '/remove_approver',