mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 21:26:17 +00:00
Added secret reminder handler on updates
This commit is contained in:
@@ -6,13 +6,7 @@ import { BotService } from "../../services";
|
|||||||
import { containsGlobPatterns, repackageSecretToRaw } from "../../helpers/secrets";
|
import { containsGlobPatterns, repackageSecretToRaw } from "../../helpers/secrets";
|
||||||
import { encryptSymmetric128BitHexKeyUTF8 } from "../../utils/crypto";
|
import { encryptSymmetric128BitHexKeyUTF8 } from "../../utils/crypto";
|
||||||
import { getAllImportedSecrets } from "../../services/SecretImportService";
|
import { getAllImportedSecrets } from "../../services/SecretImportService";
|
||||||
import {
|
import { Folder, IServiceTokenData, Membership, ServiceTokenData, User } from "../../models";
|
||||||
Folder,
|
|
||||||
IServiceTokenData,
|
|
||||||
Membership,
|
|
||||||
ServiceTokenData,
|
|
||||||
User
|
|
||||||
} from "../../models";
|
|
||||||
import { getFolderByPath } from "../../services/FolderService";
|
import { getFolderByPath } from "../../services/FolderService";
|
||||||
import { BadRequestError } from "../../utils/errors";
|
import { BadRequestError } from "../../utils/errors";
|
||||||
import { validateRequest } from "../../helpers/validation";
|
import { validateRequest } from "../../helpers/validation";
|
||||||
@@ -34,6 +28,8 @@ import {
|
|||||||
} from "../../ee/services/SecretApprovalService";
|
} from "../../ee/services/SecretApprovalService";
|
||||||
import { CommitType } from "../../ee/models/secretApprovalRequest";
|
import { CommitType } from "../../ee/models/secretApprovalRequest";
|
||||||
import { logger } from "../../utils/logging";
|
import { logger } from "../../utils/logging";
|
||||||
|
import { IRole } from "../../ee/models/role";
|
||||||
|
import { createReminder, deleteReminder } from "../../helpers/reminder";
|
||||||
|
|
||||||
const checkSecretsPermission = async ({
|
const checkSecretsPermission = async ({
|
||||||
authData,
|
authData,
|
||||||
@@ -197,10 +193,11 @@ export const getSecretsRaw = async (req: Request, res: Response) => {
|
|||||||
query: { include_imports: includeImports }
|
query: { include_imports: includeImports }
|
||||||
} = validatedData;
|
} = validatedData;
|
||||||
|
|
||||||
logger.info(`getSecretsRaw: fetch raw secrets [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [includeImports=${includeImports}]`)
|
logger.info(
|
||||||
|
`getSecretsRaw: fetch raw secrets [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [includeImports=${includeImports}]`
|
||||||
|
);
|
||||||
|
|
||||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||||
|
|
||||||
// if the service token has single scope, it will get all secrets for that scope by default
|
// if the service token has single scope, it will get all secrets for that scope by default
|
||||||
const serviceTokenDetails: IServiceTokenData = req?.serviceTokenData;
|
const serviceTokenDetails: IServiceTokenData = req?.serviceTokenData;
|
||||||
if (
|
if (
|
||||||
@@ -356,7 +353,9 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
|
|||||||
params: { secretName }
|
params: { secretName }
|
||||||
} = await validateRequest(reqValidator.GetSecretByNameRawV3, req);
|
} = await validateRequest(reqValidator.GetSecretByNameRawV3, req);
|
||||||
|
|
||||||
logger.info(`getSecretByNameRaw: fetch raw secret by name [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}] [include_imports=${include_imports}]`)
|
logger.info(
|
||||||
|
`getSecretByNameRaw: fetch raw secret by name [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}] [include_imports=${include_imports}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -481,7 +480,9 @@ export const createSecretRaw = async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
} = await validateRequest(reqValidator.CreateSecretRawV3, req);
|
} = await validateRequest(reqValidator.CreateSecretRawV3, req);
|
||||||
|
|
||||||
logger.info(`createSecretRaw: create a secret raw by name and value [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}] [skipMultilineEncoding=${skipMultilineEncoding}]`)
|
logger.info(
|
||||||
|
`createSecretRaw: create a secret raw by name and value [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}] [skipMultilineEncoding=${skipMultilineEncoding}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -628,7 +629,9 @@ export const updateSecretByNameRaw = async (req: Request, res: Response) => {
|
|||||||
body: { workspaceId, environment, secretValue, secretPath, type, skipMultilineEncoding }
|
body: { workspaceId, environment, secretValue, secretPath, type, skipMultilineEncoding }
|
||||||
} = await validateRequest(reqValidator.UpdateSecretByNameRawV3, req);
|
} = await validateRequest(reqValidator.UpdateSecretByNameRawV3, req);
|
||||||
|
|
||||||
logger.info(`updateSecretByNameRaw: update raw secret by name [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}] [skipMultilineEncoding=${skipMultilineEncoding}]`)
|
logger.info(
|
||||||
|
`updateSecretByNameRaw: update raw secret by name [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}] [skipMultilineEncoding=${skipMultilineEncoding}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -752,7 +755,9 @@ export const deleteSecretByNameRaw = async (req: Request, res: Response) => {
|
|||||||
body: { environment, secretPath, type, workspaceId }
|
body: { environment, secretPath, type, workspaceId }
|
||||||
} = await validateRequest(reqValidator.DeleteSecretByNameRawV3, req);
|
} = await validateRequest(reqValidator.DeleteSecretByNameRawV3, req);
|
||||||
|
|
||||||
logger.info(`deleteSecretByNameRaw: delete a secret by name [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}]`)
|
logger.info(
|
||||||
|
`deleteSecretByNameRaw: delete a secret by name [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -807,7 +812,9 @@ export const getSecrets = async (req: Request, res: Response) => {
|
|||||||
query: { secretPath }
|
query: { secretPath }
|
||||||
} = validatedData;
|
} = validatedData;
|
||||||
|
|
||||||
logger.info(`getSecrets: fetch encrypted secrets [environment=${environment}] [workspaceId=${workspaceId}] [includeImports=${includeImports}]`)
|
logger.info(
|
||||||
|
`getSecrets: fetch encrypted secrets [environment=${environment}] [workspaceId=${workspaceId}] [includeImports=${includeImports}]`
|
||||||
|
);
|
||||||
|
|
||||||
const { authVerifier: permissionCheckFn } = await checkSecretsPermission({
|
const { authVerifier: permissionCheckFn } = await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -863,7 +870,9 @@ export const getSecretByName = async (req: Request, res: Response) => {
|
|||||||
params: { secretName }
|
params: { secretName }
|
||||||
} = await validateRequest(reqValidator.GetSecretByNameV3, req);
|
} = await validateRequest(reqValidator.GetSecretByNameV3, req);
|
||||||
|
|
||||||
logger.info(`getSecretByName: get a single secret by name [environment=${environment}] [workspaceId=${workspaceId}] [include_imports=${include_imports}] [type=${type}]`)
|
logger.info(
|
||||||
|
`getSecretByName: get a single secret by name [environment=${environment}] [workspaceId=${workspaceId}] [include_imports=${include_imports}] [type=${type}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -915,7 +924,9 @@ export const createSecret = async (req: Request, res: Response) => {
|
|||||||
params: { secretName }
|
params: { secretName }
|
||||||
} = await validateRequest(reqValidator.CreateSecretV3, req);
|
} = await validateRequest(reqValidator.CreateSecretV3, req);
|
||||||
|
|
||||||
logger.info(`createSecret: create an encrypted secret [environment=${environment}] [workspaceId=${workspaceId}] [skipMultilineEncoding=${skipMultilineEncoding}] [type=${type}]`)
|
logger.info(
|
||||||
|
`createSecret: create an encrypted secret [environment=${environment}] [workspaceId=${workspaceId}] [skipMultilineEncoding=${skipMultilineEncoding}] [type=${type}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -932,7 +943,11 @@ export const createSecret = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (membership && type !== "personal") {
|
if (membership && type !== "personal") {
|
||||||
const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath);
|
const secretApprovalPolicy = await getSecretPolicyOfBoard(
|
||||||
|
workspaceId,
|
||||||
|
environment,
|
||||||
|
secretPath
|
||||||
|
);
|
||||||
if (secretApprovalPolicy) {
|
if (secretApprovalPolicy) {
|
||||||
const secretApprovalRequest = await generateSecretApprovalRequest({
|
const secretApprovalRequest = await generateSecretApprovalRequest({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -1024,12 +1039,16 @@ export const updateSecretByName = async (req: Request, res: Response) => {
|
|||||||
secretKeyIV,
|
secretKeyIV,
|
||||||
secretKeyTag,
|
secretKeyTag,
|
||||||
secretKeyCiphertext,
|
secretKeyCiphertext,
|
||||||
skipMultilineEncoding
|
skipMultilineEncoding,
|
||||||
|
secretReminderCron,
|
||||||
|
secretReminderNote
|
||||||
},
|
},
|
||||||
params: { secretName }
|
params: { secretName }
|
||||||
} = await validateRequest(reqValidator.UpdateSecretByNameV3, req);
|
} = await validateRequest(reqValidator.UpdateSecretByNameV3, req);
|
||||||
|
|
||||||
logger.info(`updateSecretByName: update a encrypted secret by name [environment=${environment}] [workspaceId=${workspaceId}] [skipMultilineEncoding=${skipMultilineEncoding}] [type=${type}]`)
|
logger.info(
|
||||||
|
`updateSecretByName: update a encrypted secret by name [environment=${environment}] [workspaceId=${workspaceId}] [skipMultilineEncoding=${skipMultilineEncoding}] [type=${type}]`
|
||||||
|
);
|
||||||
|
|
||||||
if (newSecretName && (!secretKeyIV || !secretKeyTag || !secretKeyCiphertext)) {
|
if (newSecretName && (!secretKeyIV || !secretKeyTag || !secretKeyCiphertext)) {
|
||||||
throw BadRequestError({ message: "Missing encrypted key" });
|
throw BadRequestError({ message: "Missing encrypted key" });
|
||||||
@@ -1050,7 +1069,11 @@ export const updateSecretByName = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (membership && type !== "personal") {
|
if (membership && type !== "personal") {
|
||||||
const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath);
|
const secretApprovalPolicy = await getSecretPolicyOfBoard(
|
||||||
|
workspaceId,
|
||||||
|
environment,
|
||||||
|
secretPath
|
||||||
|
);
|
||||||
if (secretApprovalPolicy) {
|
if (secretApprovalPolicy) {
|
||||||
const secretApprovalRequest = await generateSecretApprovalRequest({
|
const secretApprovalRequest = await generateSecretApprovalRequest({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -1084,6 +1107,38 @@ export const updateSecretByName = async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type !== "personal") {
|
||||||
|
const existingSecret = await SecretService.getSecret({
|
||||||
|
secretName,
|
||||||
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
|
environment,
|
||||||
|
type,
|
||||||
|
secretPath,
|
||||||
|
authData: req.authData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
(secretReminderCron && existingSecret.secretReminderCron !== secretReminderCron) ||
|
||||||
|
(secretReminderNote && existingSecret.secretReminderNote !== secretReminderNote)
|
||||||
|
) {
|
||||||
|
await createReminder(existingSecret, {
|
||||||
|
_id: existingSecret._id,
|
||||||
|
secretReminderCron,
|
||||||
|
secretReminderNote,
|
||||||
|
workspace: existingSecret.workspace
|
||||||
|
});
|
||||||
|
} else if (
|
||||||
|
secretReminderCron === null &&
|
||||||
|
secretReminderNote === null &&
|
||||||
|
existingSecret.secretReminderCron
|
||||||
|
) {
|
||||||
|
await deleteReminder({
|
||||||
|
_id: existingSecret._id,
|
||||||
|
secretReminderCron: existingSecret.secretReminderCron
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const secret = await SecretService.updateSecret({
|
const secret = await SecretService.updateSecret({
|
||||||
secretName,
|
secretName,
|
||||||
workspaceId: new Types.ObjectId(workspaceId),
|
workspaceId: new Types.ObjectId(workspaceId),
|
||||||
@@ -1094,6 +1149,8 @@ export const updateSecretByName = async (req: Request, res: Response) => {
|
|||||||
newSecretName,
|
newSecretName,
|
||||||
secretValueCiphertext,
|
secretValueCiphertext,
|
||||||
secretValueIV,
|
secretValueIV,
|
||||||
|
secretReminderCron,
|
||||||
|
secretReminderNote,
|
||||||
secretValueTag,
|
secretValueTag,
|
||||||
secretPath,
|
secretPath,
|
||||||
tags,
|
tags,
|
||||||
@@ -1130,7 +1187,9 @@ export const deleteSecretByName = async (req: Request, res: Response) => {
|
|||||||
params: { secretName }
|
params: { secretName }
|
||||||
} = await validateRequest(reqValidator.DeleteSecretByNameV3, req);
|
} = await validateRequest(reqValidator.DeleteSecretByNameV3, req);
|
||||||
|
|
||||||
logger.info(`deleteSecretByName: delete a encrypted secret by name [environment=${environment}] [workspaceId=${workspaceId}] [type=${type}]`)
|
logger.info(
|
||||||
|
`deleteSecretByName: delete a encrypted secret by name [environment=${environment}] [workspaceId=${workspaceId}] [type=${type}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -1147,7 +1206,11 @@ export const deleteSecretByName = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (membership && type !== "personal") {
|
if (membership && type !== "personal") {
|
||||||
const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath);
|
const secretApprovalPolicy = await getSecretPolicyOfBoard(
|
||||||
|
workspaceId,
|
||||||
|
environment,
|
||||||
|
secretPath
|
||||||
|
);
|
||||||
if (secretApprovalPolicy) {
|
if (secretApprovalPolicy) {
|
||||||
const secretApprovalRequest = await generateSecretApprovalRequest({
|
const secretApprovalRequest = await generateSecretApprovalRequest({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -1197,7 +1260,9 @@ export const createSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
body: { secrets, secretPath, environment, workspaceId }
|
body: { secrets, secretPath, environment, workspaceId }
|
||||||
} = await validateRequest(reqValidator.CreateSecretByNameBatchV3, req);
|
} = await validateRequest(reqValidator.CreateSecretByNameBatchV3, req);
|
||||||
|
|
||||||
logger.info(`createSecretByNameBatch: create a list of secrets by their names [environment=${environment}] [workspaceId=${workspaceId}] [secretsLength=${secrets?.length}]`)
|
logger.info(
|
||||||
|
`createSecretByNameBatch: create a list of secrets by their names [environment=${environment}] [workspaceId=${workspaceId}] [secretsLength=${secrets?.length}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -1214,7 +1279,11 @@ export const createSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (membership) {
|
if (membership) {
|
||||||
const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath);
|
const secretApprovalPolicy = await getSecretPolicyOfBoard(
|
||||||
|
workspaceId,
|
||||||
|
environment,
|
||||||
|
secretPath
|
||||||
|
);
|
||||||
if (secretApprovalPolicy) {
|
if (secretApprovalPolicy) {
|
||||||
const secretApprovalRequest = await generateSecretApprovalRequest({
|
const secretApprovalRequest = await generateSecretApprovalRequest({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -1258,7 +1327,9 @@ export const updateSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
body: { secrets, secretPath, environment, workspaceId }
|
body: { secrets, secretPath, environment, workspaceId }
|
||||||
} = await validateRequest(reqValidator.UpdateSecretByNameBatchV3, req);
|
} = await validateRequest(reqValidator.UpdateSecretByNameBatchV3, req);
|
||||||
|
|
||||||
logger.info(`updateSecretByNameBatch: update a list of secrets by their names [environment=${environment}] [workspaceId=${workspaceId}] [secretsLength=${secrets?.length}]`)
|
logger.info(
|
||||||
|
`updateSecretByNameBatch: update a list of secrets by their names [environment=${environment}] [workspaceId=${workspaceId}] [secretsLength=${secrets?.length}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -1275,7 +1346,11 @@ export const updateSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (membership) {
|
if (membership) {
|
||||||
const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath);
|
const secretApprovalPolicy = await getSecretPolicyOfBoard(
|
||||||
|
workspaceId,
|
||||||
|
environment,
|
||||||
|
secretPath
|
||||||
|
);
|
||||||
if (secretApprovalPolicy) {
|
if (secretApprovalPolicy) {
|
||||||
const secretApprovalRequest = await generateSecretApprovalRequest({
|
const secretApprovalRequest = await generateSecretApprovalRequest({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -1319,7 +1394,9 @@ export const deleteSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
body: { secrets, secretPath, environment, workspaceId }
|
body: { secrets, secretPath, environment, workspaceId }
|
||||||
} = await validateRequest(reqValidator.DeleteSecretByNameBatchV3, req);
|
} = await validateRequest(reqValidator.DeleteSecretByNameBatchV3, req);
|
||||||
|
|
||||||
logger.info(`deleteSecretByNameBatch: delete a list of secrets by their names [environment=${environment}] [workspaceId=${workspaceId}] [secretsLength=${secrets?.length}]`)
|
logger.info(
|
||||||
|
`deleteSecretByNameBatch: delete a list of secrets by their names [environment=${environment}] [workspaceId=${workspaceId}] [secretsLength=${secrets?.length}]`
|
||||||
|
);
|
||||||
|
|
||||||
await checkSecretsPermission({
|
await checkSecretsPermission({
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
@@ -1336,7 +1413,11 @@ export const deleteSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (membership) {
|
if (membership) {
|
||||||
const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath);
|
const secretApprovalPolicy = await getSecretPolicyOfBoard(
|
||||||
|
workspaceId,
|
||||||
|
environment,
|
||||||
|
secretPath
|
||||||
|
);
|
||||||
if (secretApprovalPolicy) {
|
if (secretApprovalPolicy) {
|
||||||
const secretApprovalRequest = await generateSecretApprovalRequest({
|
const secretApprovalRequest = await generateSecretApprovalRequest({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -1373,4 +1454,4 @@ export const deleteSecretByNameBatch = async (req: Request, res: Response) => {
|
|||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
secrets: deletedSecrets
|
secrets: deletedSecrets
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user