mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-25 14:05:03 +00:00
merge with own change
This commit is contained in:
@ -1,10 +1,15 @@
|
||||
import express, { Request, Response } from 'express';
|
||||
import { requireAuth, validateRequest } from '../../middleware';
|
||||
import { requireAuth, requireWorkspaceAuth, validateRequest } from '../../middleware';
|
||||
import { ISecret, Secret } from '../../models';
|
||||
import { decryptSymmetric } from '../../utils/crypto';
|
||||
import { getLogger } from '../../utils/logger';
|
||||
import { body, param, query, check } from 'express-validator';
|
||||
import { BadRequestError } from '../../utils/errors';
|
||||
import { BadRequestError, UnauthorizedRequestError } from '../../utils/errors';
|
||||
import { ADMIN, MEMBER, COMPLETED, GRANTED } from '../../variables';
|
||||
import { ModifySecretPayload } from '../../types/secret';
|
||||
import { AnyBulkWriteOperation } from 'mongodb';
|
||||
import to from 'await-to-js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
@ -13,6 +18,10 @@ const router = express.Router();
|
||||
router.post(
|
||||
'/', requireAuth,
|
||||
body('secret').exists().isObject(),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
acceptedStatuses: [COMPLETED, GRANTED]
|
||||
}),
|
||||
async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { secret }: { secret: ISecret[] } = req.body;
|
||||
@ -29,6 +38,10 @@ router.post(
|
||||
*/
|
||||
router.post(
|
||||
'/bulk-create', requireAuth,
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
acceptedStatuses: [COMPLETED, GRANTED]
|
||||
}),
|
||||
body('secrets').exists().isArray().custom((value) => value.every((item: ISecret) => typeof item === 'object')),
|
||||
async (req: Request, res: Response) => {
|
||||
try {
|
||||
@ -46,6 +59,10 @@ router.post(
|
||||
*/
|
||||
router.get(
|
||||
'/:secretId', requireAuth, param('secretId').exists().trim(),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
acceptedStatuses: [COMPLETED, GRANTED]
|
||||
}),
|
||||
validateRequest, async (req: Request, res: Response) => {
|
||||
try {
|
||||
const secretFromDB = await Secret.findById(req.params.secretId)
|
||||
@ -61,6 +78,10 @@ router.get(
|
||||
*/
|
||||
router.get(
|
||||
'/:bulk', requireAuth, param('secretId').exists().trim(),
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
acceptedStatuses: [COMPLETED, GRANTED]
|
||||
}),
|
||||
validateRequest, async (req: Request, res: Response) => {
|
||||
try {
|
||||
const secretFromDB = await Secret.findById(req.params.secretId)
|
||||
@ -77,6 +98,10 @@ router.get(
|
||||
router.delete(
|
||||
'/:secretId',
|
||||
requireAuth,
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
acceptedStatuses: [COMPLETED, GRANTED]
|
||||
}),
|
||||
param('secretId').exists().trim(),
|
||||
validateRequest, async (req: Request, res: Response) => {
|
||||
try {
|
||||
@ -96,6 +121,10 @@ router.delete(
|
||||
router.delete(
|
||||
'/batch',
|
||||
requireAuth,
|
||||
requireWorkspaceAuth({
|
||||
acceptedRoles: [ADMIN, MEMBER],
|
||||
acceptedStatuses: [COMPLETED, GRANTED]
|
||||
}),
|
||||
body('secretIds').exists().isArray(),
|
||||
validateRequest, async (req: Request, res: Response) => {
|
||||
try {
|
||||
@ -111,25 +140,66 @@ router.delete(
|
||||
);
|
||||
|
||||
/**
|
||||
* Apply modifications to many existing secrets
|
||||
* Apply modifications to many existing secrets in a given workspace and environment
|
||||
* Note: although we do not check access for environments, we will in the future
|
||||
*/
|
||||
router.patch(
|
||||
'/bulk-update',
|
||||
'/bulk-modify/:workspaceId/:environmentName',
|
||||
requireAuth,
|
||||
body('secrets').exists().isArray().custom((value) => value.every((item: ISecret) => typeof item === 'object')),
|
||||
param('workspaceId').exists().trim(),
|
||||
param('environmentName').exists().trim(),
|
||||
// requireWorkspaceAuth({
|
||||
// acceptedRoles: [ADMIN, MEMBER],
|
||||
// acceptedStatuses: [COMPLETED, GRANTED]
|
||||
// }),
|
||||
validateRequest, async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { secrets }: { secrets: ISecret[] } = req.body;
|
||||
const { workspaceId, environmentName } = req.params
|
||||
const secretsModificationsRequested: ModifySecretPayload[] = req.body.secrets;
|
||||
|
||||
const operations = secrets.map((secretToUpdate: ISecret) => ({
|
||||
updateOne: { filter: { _id: secretToUpdate._id }, update: secretToUpdate },
|
||||
}));
|
||||
const secretsUserCanModify: ISecret[] = await Secret.find({ workspace: workspaceId, environment: environmentName })
|
||||
|
||||
const bulkModificationInfo = await Secret.bulkWrite(operations);
|
||||
const secretsUserCanModifyMapBySecretId: Map<string, ISecret> = new Map<string, ISecret>();
|
||||
secretsUserCanModify.forEach(secret => secretsUserCanModifyMapBySecretId.set(secret._id.toString(), secret))
|
||||
|
||||
return res.status(200).json(bulkModificationInfo)
|
||||
} catch (error) {
|
||||
throw BadRequestError({ message: `Unable to process the bulk update. Double check the ids of the secrets` })
|
||||
// Check if the entity has access to the secret ids it wants to modify
|
||||
const updateOperationsToPerform: AnyBulkWriteOperation<ISecret>[] = []
|
||||
secretsModificationsRequested.forEach(userModifiedSecret => {
|
||||
const canModifyRequestedSecret = secretsUserCanModifyMapBySecretId.has(userModifiedSecret._id.toString())
|
||||
if (canModifyRequestedSecret) {
|
||||
const oldSecretInDB = secretsUserCanModifyMapBySecretId.get(userModifiedSecret._id.toString())
|
||||
|
||||
if (oldSecretInDB !== undefined) {
|
||||
oldSecretInDB.secretKeyCiphertext = userModifiedSecret.secretKeyCiphertext
|
||||
oldSecretInDB.secretKeyIV = userModifiedSecret.secretKeyIV
|
||||
oldSecretInDB.secretKeyTag = userModifiedSecret.secretKeyTag
|
||||
oldSecretInDB.secretKeyHash = userModifiedSecret.secretKeyHash
|
||||
oldSecretInDB.secretValueCiphertext = userModifiedSecret.secretValueCiphertext
|
||||
oldSecretInDB.secretValueIV = userModifiedSecret.secretValueIV
|
||||
oldSecretInDB.secretValueTag = userModifiedSecret.secretValueTag
|
||||
oldSecretInDB.secretValueHash = userModifiedSecret.secretValueHash
|
||||
oldSecretInDB.secretCommentCiphertext = userModifiedSecret.secretCommentCiphertext
|
||||
oldSecretInDB.secretCommentIV = userModifiedSecret.secretCommentIV
|
||||
oldSecretInDB.secretCommentTag = userModifiedSecret.secretCommentTag
|
||||
oldSecretInDB.secretCommentHash = userModifiedSecret.secretCommentHash
|
||||
|
||||
const updateOperation = { updateOne: { filter: { _id: oldSecretInDB._id, workspace: oldSecretInDB.workspace }, update: { $inc: { version: 1 }, $set: oldSecretInDB } } }
|
||||
updateOperationsToPerform.push(updateOperation)
|
||||
}
|
||||
} else {
|
||||
throw UnauthorizedRequestError({ message: "You do not have permission to modify one or more of the requested secrets" })
|
||||
}
|
||||
})
|
||||
|
||||
const bulkModificationInfo = await Secret.bulkWrite(updateOperationsToPerform);
|
||||
|
||||
return res.status(200).json({
|
||||
bulkModificationInfo
|
||||
})
|
||||
|
||||
} catch (e) {
|
||||
throw BadRequestError()
|
||||
}
|
||||
}
|
||||
);
|
||||
|
4
backend/src/types/secret/index.ts
Normal file
4
backend/src/types/secret/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { Omit } from 'utility-types';
|
||||
import { ISecret } from '../../models';
|
||||
|
||||
export type ModifySecretPayload = Omit<ISecret, "user" | "version" | "environment" | "workspace">;
|
30
package-lock.json
generated
30
package-lock.json
generated
@ -6,6 +6,10 @@
|
||||
"": {
|
||||
"name": "infisical",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"await-to-js": "^3.0.0",
|
||||
"utility-types": "^3.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.29.0",
|
||||
"husky": "^8.0.2"
|
||||
@ -169,6 +173,14 @@
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/await-to-js": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz",
|
||||
"integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@ -1092,6 +1104,14 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/utility-types": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
|
||||
"integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
@ -1248,6 +1268,11 @@
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true
|
||||
},
|
||||
"await-to-js": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz",
|
||||
"integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g=="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@ -1910,6 +1935,11 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"utility-types": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
|
||||
"integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg=="
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
@ -21,5 +21,9 @@
|
||||
"devDependencies": {
|
||||
"eslint": "^8.29.0",
|
||||
"husky": "^8.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"await-to-js": "^3.0.0",
|
||||
"utility-types": "^3.10.0"
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user