mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: made raw secret endpoints and normal e2ee ones to be same functionality
This commit is contained in:
@@ -608,7 +608,9 @@ export const RAW_SECRETS = {
|
||||
skipMultilineEncoding: "Skip multiline encoding for the secret value.",
|
||||
type: "The type of the secret to create.",
|
||||
workspaceId: "The ID of the project to create the secret in.",
|
||||
tagIds: "The ID of the tags to be attached to the created secret."
|
||||
tagIds: "The ID of the tags to be attached to the created secret.",
|
||||
secretReminderRepeatDays: "Interval for secret rotation notifications, measured in days",
|
||||
secretReminderNote: "Note to be attached in notification email"
|
||||
},
|
||||
GET: {
|
||||
expand: "Whether or not to expand secret references",
|
||||
@@ -631,7 +633,10 @@ export const RAW_SECRETS = {
|
||||
type: "The type of the secret to update.",
|
||||
projectSlug: "The slug of the project to update the secret in.",
|
||||
workspaceId: "The ID of the project to update the secret in.",
|
||||
tagIds: "The ID of the tags to be attached to the updated secret."
|
||||
tagIds: "The ID of the tags to be attached to the updated secret.",
|
||||
secretReminderRepeatDays: "Interval for secret rotation notifications, measured in days",
|
||||
secretReminderNote: "Note to be attached in notification email",
|
||||
newSecretName: "The new name for the secret"
|
||||
},
|
||||
DELETE: {
|
||||
secretName: "The name of the secret to delete.",
|
||||
|
||||
@@ -703,6 +703,7 @@ export const registerRoutes = async (
|
||||
});
|
||||
const secretImportService = secretImportServiceFactory({
|
||||
licenseService,
|
||||
projectBotService,
|
||||
projectEnvDAL,
|
||||
folderDAL,
|
||||
permissionService,
|
||||
|
||||
@@ -63,7 +63,13 @@ export const secretRawSchema = z.object({
|
||||
type: z.string(),
|
||||
secretKey: z.string(),
|
||||
secretValue: z.string(),
|
||||
secretComment: z.string().optional()
|
||||
secretComment: z.string().optional(),
|
||||
secretReminderNote: z.string().nullable().optional(),
|
||||
secretReminderRepeatDays: z.number().nullable().optional(),
|
||||
skipMultilineEncoding: z.boolean().default(false).nullable().optional(),
|
||||
metadata: z.unknown().nullable().optional(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
});
|
||||
|
||||
export const ProjectPermissionSchema = z.object({
|
||||
|
||||
@@ -8,6 +8,8 @@ import { readLimit, secretsLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
|
||||
import { secretRawSchema } from "../sanitizedSchemas";
|
||||
|
||||
export const registerSecretImportRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
method: "POST",
|
||||
@@ -353,4 +355,48 @@ export const registerSecretImportRouter = async (server: FastifyZodProvider) =>
|
||||
return { secrets: importedSecrets };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
url: "/secrets/raw",
|
||||
method: "GET",
|
||||
config: {
|
||||
rateLimit: secretsLimit
|
||||
},
|
||||
schema: {
|
||||
querystring: z.object({
|
||||
workspaceId: z.string().trim(),
|
||||
environment: z.string().trim(),
|
||||
path: z.string().trim().default("/").transform(removeTrailingSlash)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
secrets: z
|
||||
.object({
|
||||
secretPath: z.string(),
|
||||
environment: z.string(),
|
||||
environmentInfo: z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
slug: z.string()
|
||||
}),
|
||||
folderId: z.string().optional(),
|
||||
secrets: secretRawSchema.array()
|
||||
})
|
||||
.array()
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const importedSecrets = await server.services.secretImport.getRawSecretsFromImports({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
...req.query,
|
||||
projectId: req.query.workspaceId
|
||||
});
|
||||
return { secrets: importedSecrets };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -186,7 +186,15 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
200: z.object({
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretPath: z.string().optional()
|
||||
secretPath: z.string().optional(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
name: true,
|
||||
color: true
|
||||
})
|
||||
.array()
|
||||
.optional()
|
||||
})
|
||||
.array(),
|
||||
imports: z
|
||||
@@ -194,7 +202,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretPath: z.string(),
|
||||
environment: z.string(),
|
||||
folderId: z.string().optional(),
|
||||
secrets: secretRawSchema.array()
|
||||
secrets: secretRawSchema.omit({ createdAt: true, updatedAt: true }).array()
|
||||
})
|
||||
.array()
|
||||
.optional()
|
||||
@@ -425,7 +433,13 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretComment: z.string().trim().optional().default("").describe(RAW_SECRETS.CREATE.secretComment),
|
||||
tagIds: z.string().array().optional().describe(RAW_SECRETS.CREATE.tagIds),
|
||||
skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.CREATE.skipMultilineEncoding),
|
||||
type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.CREATE.type)
|
||||
type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.CREATE.type),
|
||||
secretReminderRepeatDays: z
|
||||
.number()
|
||||
.optional()
|
||||
.nullable()
|
||||
.describe(RAW_SECRETS.CREATE.secretReminderRepeatDays),
|
||||
secretReminderNote: z.string().optional().nullable().describe(RAW_SECRETS.CREATE.secretReminderNote)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
@@ -448,7 +462,9 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretValue: req.body.secretValue,
|
||||
skipMultilineEncoding: req.body.skipMultilineEncoding,
|
||||
secretComment: req.body.secretComment,
|
||||
tagIds: req.body.tagIds
|
||||
tagIds: req.body.tagIds,
|
||||
secretReminderNote: req.body.secretReminderNote,
|
||||
secretReminderRepeatDays: req.body.secretReminderRepeatDays
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
@@ -514,7 +530,16 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
.describe(RAW_SECRETS.UPDATE.secretPath),
|
||||
skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.UPDATE.skipMultilineEncoding),
|
||||
type: z.nativeEnum(SecretType).default(SecretType.Shared).describe(RAW_SECRETS.UPDATE.type),
|
||||
tagIds: z.string().array().optional().describe(RAW_SECRETS.UPDATE.tagIds)
|
||||
tagIds: z.string().array().optional().describe(RAW_SECRETS.UPDATE.tagIds),
|
||||
metadata: z.record(z.string()).optional(),
|
||||
secretReminderNote: z.string().optional().nullable().describe(RAW_SECRETS.UPDATE.secretReminderNote),
|
||||
secretReminderRepeatDays: z
|
||||
.number()
|
||||
.optional()
|
||||
.nullable()
|
||||
.describe(RAW_SECRETS.UPDATE.secretReminderRepeatDays),
|
||||
newSecretName: z.string().min(1).optional().describe(RAW_SECRETS.UPDATE.newSecretName),
|
||||
secretComment: z.string().optional().describe(RAW_SECRETS.UPDATE.secretComment)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
@@ -536,7 +561,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
type: req.body.type,
|
||||
secretValue: req.body.secretValue,
|
||||
skipMultilineEncoding: req.body.skipMultilineEncoding,
|
||||
tagIds: req.body.tagIds
|
||||
tagIds: req.body.tagIds,
|
||||
secretReminderRepeatDays: req.body.secretReminderRepeatDays,
|
||||
secretReminderNote: req.body.secretReminderNote,
|
||||
metadata: req.body.metadata,
|
||||
newSecretName: req.body.newSecretName,
|
||||
secretComment: req.body.secretComment
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
@@ -1760,7 +1790,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
],
|
||||
body: z.object({
|
||||
projectSlug: z.string().trim().describe(RAW_SECRETS.CREATE.projectSlug),
|
||||
projectSlug: z.string().trim().optional().describe(RAW_SECRETS.UPDATE.projectSlug),
|
||||
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.UPDATE.workspaceId),
|
||||
environment: z.string().trim().describe(RAW_SECRETS.CREATE.environment),
|
||||
secretPath: z
|
||||
.string()
|
||||
@@ -1776,7 +1807,9 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
.transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim()))
|
||||
.describe(RAW_SECRETS.CREATE.secretValue),
|
||||
secretComment: z.string().trim().optional().default("").describe(RAW_SECRETS.CREATE.secretComment),
|
||||
skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.CREATE.skipMultilineEncoding)
|
||||
skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.CREATE.skipMultilineEncoding),
|
||||
metadata: z.record(z.string()).optional(),
|
||||
tagIds: z.string().array().optional().describe(RAW_SECRETS.CREATE.tagIds)
|
||||
})
|
||||
.array()
|
||||
.min(1)
|
||||
@@ -1799,6 +1832,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretPath,
|
||||
environment,
|
||||
projectSlug,
|
||||
projectId: req.body.workspaceId,
|
||||
secrets: inputSecrets
|
||||
});
|
||||
|
||||
@@ -1849,7 +1883,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
],
|
||||
body: z.object({
|
||||
projectSlug: z.string().trim().describe(RAW_SECRETS.UPDATE.projectSlug),
|
||||
projectSlug: z.string().trim().optional().describe(RAW_SECRETS.DELETE.projectSlug),
|
||||
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.DELETE.workspaceId),
|
||||
environment: z.string().trim().describe(RAW_SECRETS.UPDATE.environment),
|
||||
secretPath: z
|
||||
.string()
|
||||
@@ -1865,7 +1900,15 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
.transform((val) => (val.at(-1) === "\n" ? `${val.trim()}\n` : val.trim()))
|
||||
.describe(RAW_SECRETS.UPDATE.secretValue),
|
||||
secretComment: z.string().trim().optional().describe(RAW_SECRETS.UPDATE.secretComment),
|
||||
skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.UPDATE.skipMultilineEncoding)
|
||||
skipMultilineEncoding: z.boolean().optional().describe(RAW_SECRETS.UPDATE.skipMultilineEncoding),
|
||||
newSecretName: z.string().min(1).optional().describe(RAW_SECRETS.UPDATE.newSecretName),
|
||||
tagIds: z.string().array().optional().describe(RAW_SECRETS.UPDATE.tagIds),
|
||||
secretReminderNote: z.string().optional().nullable().describe(RAW_SECRETS.UPDATE.secretReminderNote),
|
||||
secretReminderRepeatDays: z
|
||||
.number()
|
||||
.optional()
|
||||
.nullable()
|
||||
.describe(RAW_SECRETS.UPDATE.secretReminderRepeatDays)
|
||||
})
|
||||
.array()
|
||||
.min(1)
|
||||
@@ -1887,6 +1930,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretPath,
|
||||
environment,
|
||||
projectSlug,
|
||||
projectId: req.body.workspaceId,
|
||||
secrets: inputSecrets
|
||||
});
|
||||
|
||||
@@ -1937,7 +1981,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
],
|
||||
body: z.object({
|
||||
projectSlug: z.string().trim().describe(RAW_SECRETS.DELETE.projectSlug),
|
||||
projectSlug: z.string().trim().optional().describe(RAW_SECRETS.DELETE.projectSlug),
|
||||
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.DELETE.workspaceId),
|
||||
environment: z.string().trim().describe(RAW_SECRETS.DELETE.environment),
|
||||
secretPath: z
|
||||
.string()
|
||||
@@ -1947,7 +1992,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
.describe(RAW_SECRETS.DELETE.secretPath),
|
||||
secrets: z
|
||||
.object({
|
||||
secretKey: z.string().trim().describe(RAW_SECRETS.DELETE.secretName)
|
||||
secretKey: z.string().trim().describe(RAW_SECRETS.DELETE.secretName),
|
||||
type: z.nativeEnum(SecretType).default(SecretType.Shared)
|
||||
})
|
||||
.array()
|
||||
.min(1)
|
||||
@@ -1969,6 +2015,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
environment,
|
||||
projectSlug,
|
||||
secretPath,
|
||||
projectId: req.body.workspaceId,
|
||||
secrets: inputSecrets
|
||||
});
|
||||
|
||||
|
||||
@@ -10,8 +10,10 @@ import { getReplicationFolderName } from "@app/ee/services/secret-replication/se
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
import { TProjectBotServiceFactory } from "../project-bot/project-bot-service";
|
||||
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||
import { TSecretDALFactory } from "../secret/secret-dal";
|
||||
import { decryptSecretRaw } from "../secret/secret-fns";
|
||||
import { TSecretQueueFactory } from "../secret/secret-queue";
|
||||
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
|
||||
import { TSecretImportDALFactory } from "./secret-import-dal";
|
||||
@@ -29,6 +31,7 @@ type TSecretImportServiceFactoryDep = {
|
||||
secretImportDAL: TSecretImportDALFactory;
|
||||
folderDAL: TSecretFolderDALFactory;
|
||||
secretDAL: Pick<TSecretDALFactory, "find">;
|
||||
projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">;
|
||||
projectDAL: Pick<TProjectDALFactory, "checkProjectUpgradeStatus">;
|
||||
projectEnvDAL: TProjectEnvDALFactory;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
@@ -48,7 +51,8 @@ export const secretImportServiceFactory = ({
|
||||
projectDAL,
|
||||
secretDAL,
|
||||
secretQueueService,
|
||||
licenseService
|
||||
licenseService,
|
||||
projectBotService
|
||||
}: TSecretImportServiceFactoryDep) => {
|
||||
const createImport = async ({
|
||||
environment,
|
||||
@@ -449,12 +453,61 @@ export const secretImportServiceFactory = ({
|
||||
return fnSecretsFromImports({ allowedImports, folderDAL, secretDAL, secretImportDAL });
|
||||
};
|
||||
|
||||
const getRawSecretsFromImports = async ({
|
||||
path: secretPath,
|
||||
environment,
|
||||
projectId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorId,
|
||||
actorOrgId
|
||||
}: TGetSecretsFromImportDTO) => {
|
||||
const { permission } = await permissionService.getProjectPermission(
|
||||
actor,
|
||||
actorId,
|
||||
projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||
);
|
||||
const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath);
|
||||
if (!folder) return [];
|
||||
// this will already order by position
|
||||
// so anything based on this order will also be in right position
|
||||
const secretImports = await secretImportDAL.find({ folderId: folder.id, isReplication: false });
|
||||
|
||||
const allowedImports = secretImports.filter(({ importEnv, importPath }) =>
|
||||
permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment: importEnv.slug,
|
||||
secretPath: importPath
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
const botKey = await projectBotService.getBotKey(projectId);
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
|
||||
const importedSecrets = await fnSecretsFromImports({ allowedImports, folderDAL, secretDAL, secretImportDAL });
|
||||
return importedSecrets.map((el) => ({
|
||||
...el,
|
||||
secrets: el.secrets.map((encryptedSecret) =>
|
||||
decryptSecretRaw({ ...encryptedSecret, workspace: projectId, environment, secretPath }, botKey)
|
||||
)
|
||||
}));
|
||||
};
|
||||
|
||||
return {
|
||||
createImport,
|
||||
updateImport,
|
||||
deleteImport,
|
||||
getImports,
|
||||
getSecretsFromImports,
|
||||
getRawSecretsFromImports,
|
||||
resyncSecretImportReplication,
|
||||
fnSecretsFromImports
|
||||
};
|
||||
|
||||
@@ -407,7 +407,12 @@ export const decryptSecretRaw = (
|
||||
id: secret.id,
|
||||
user: secret.userId,
|
||||
tags: secret.tags,
|
||||
skipMultilineEncoding: secret.skipMultilineEncoding
|
||||
skipMultilineEncoding: secret.skipMultilineEncoding,
|
||||
secretReminderRepeatDays: secret.secretReminderRepeatDays,
|
||||
secretReminderNote: secret.secretReminderNote,
|
||||
metadata: secret.metadata,
|
||||
createdAt: secret.createdAt,
|
||||
updatedAt: secret.updatedAt
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1176,7 +1176,9 @@ export const secretServiceFactory = ({
|
||||
secretValue,
|
||||
secretComment,
|
||||
skipMultilineEncoding,
|
||||
tagIds
|
||||
tagIds,
|
||||
secretReminderNote,
|
||||
secretReminderRepeatDays
|
||||
}: TCreateSecretRawDTO) => {
|
||||
const botKey = await projectBotService.getBotKey(projectId);
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
@@ -1205,6 +1207,8 @@ export const secretServiceFactory = ({
|
||||
secretCommentIV: secretCommentEncrypted.iv,
|
||||
secretCommentTag: secretCommentEncrypted.tag,
|
||||
skipMultilineEncoding,
|
||||
secretReminderRepeatDays,
|
||||
secretReminderNote,
|
||||
tags: tagIds
|
||||
});
|
||||
|
||||
@@ -1223,12 +1227,19 @@ export const secretServiceFactory = ({
|
||||
secretPath,
|
||||
secretValue,
|
||||
skipMultilineEncoding,
|
||||
tagIds
|
||||
tagIds,
|
||||
secretReminderNote,
|
||||
secretReminderRepeatDays,
|
||||
metadata,
|
||||
secretComment,
|
||||
newSecretName
|
||||
}: TUpdateSecretRawDTO) => {
|
||||
const botKey = await projectBotService.getBotKey(projectId);
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
|
||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(newSecretName || secretName, botKey);
|
||||
|
||||
const secret = await updateSecret({
|
||||
secretName,
|
||||
@@ -1244,7 +1255,17 @@ export const secretServiceFactory = ({
|
||||
secretValueIV: secretValueEncrypted.iv,
|
||||
secretValueTag: secretValueEncrypted.tag,
|
||||
skipMultilineEncoding,
|
||||
tags: tagIds
|
||||
tags: tagIds,
|
||||
metadata,
|
||||
secretReminderRepeatDays,
|
||||
secretReminderNote,
|
||||
newSecretName,
|
||||
secretKeyIV: secretKeyEncrypted.iv,
|
||||
secretKeyTag: secretKeyEncrypted.tag,
|
||||
secretKeyCiphertext: secretKeyEncrypted.ciphertext,
|
||||
secretCommentIV: secretCommentEncrypted.iv,
|
||||
secretCommentTag: secretCommentEncrypted.tag,
|
||||
secretCommentCiphertext: secretCommentEncrypted.ciphertext
|
||||
});
|
||||
|
||||
await snapshotService.performSnapshot(secret.folderId);
|
||||
@@ -1283,6 +1304,7 @@ export const secretServiceFactory = ({
|
||||
const createManySecretsRaw = async ({
|
||||
actorId,
|
||||
projectSlug,
|
||||
projectId: optionalProjectId,
|
||||
environment,
|
||||
actor,
|
||||
actorOrgId,
|
||||
@@ -1290,9 +1312,16 @@ export const secretServiceFactory = ({
|
||||
secretPath,
|
||||
secrets: inputSecrets = []
|
||||
}: TCreateManySecretRawDTO) => {
|
||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||
const projectId = project.id;
|
||||
if (!projectSlug && !optionalProjectId)
|
||||
throw new BadRequestError({ message: "Must provide either project slug or projectId" });
|
||||
|
||||
let projectId = optionalProjectId as string;
|
||||
// pick either project slug or projectid
|
||||
if (!optionalProjectId && projectSlug) {
|
||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||
projectId = project.id;
|
||||
}
|
||||
|
||||
const botKey = await projectBotService.getBotKey(projectId);
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
@@ -1305,24 +1334,28 @@ export const secretServiceFactory = ({
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
secrets: inputSecrets.map(({ secretComment, secretKey, secretValue, skipMultilineEncoding }) => {
|
||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretKey, botKey);
|
||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||
return {
|
||||
secretName: secretKey,
|
||||
skipMultilineEncoding,
|
||||
secretKeyCiphertext: secretKeyEncrypted.ciphertext,
|
||||
secretKeyIV: secretKeyEncrypted.iv,
|
||||
secretKeyTag: secretKeyEncrypted.tag,
|
||||
secretValueCiphertext: secretValueEncrypted.ciphertext,
|
||||
secretValueIV: secretValueEncrypted.iv,
|
||||
secretValueTag: secretValueEncrypted.tag,
|
||||
secretCommentCiphertext: secretCommentEncrypted.ciphertext,
|
||||
secretCommentIV: secretCommentEncrypted.iv,
|
||||
secretCommentTag: secretCommentEncrypted.tag
|
||||
};
|
||||
})
|
||||
secrets: inputSecrets.map(
|
||||
({ secretComment, secretKey, metadata, tagIds, secretValue, skipMultilineEncoding }) => {
|
||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretKey, botKey);
|
||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||
return {
|
||||
secretName: secretKey,
|
||||
skipMultilineEncoding,
|
||||
secretKeyCiphertext: secretKeyEncrypted.ciphertext,
|
||||
secretKeyIV: secretKeyEncrypted.iv,
|
||||
secretKeyTag: secretKeyEncrypted.tag,
|
||||
secretValueCiphertext: secretValueEncrypted.ciphertext,
|
||||
secretValueIV: secretValueEncrypted.iv,
|
||||
secretValueTag: secretValueEncrypted.tag,
|
||||
secretCommentCiphertext: secretCommentEncrypted.ciphertext,
|
||||
secretCommentIV: secretCommentEncrypted.iv,
|
||||
secretCommentTag: secretCommentEncrypted.tag,
|
||||
tags: tagIds,
|
||||
metadata
|
||||
};
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
return secrets.map((secret) =>
|
||||
@@ -1333,6 +1366,7 @@ export const secretServiceFactory = ({
|
||||
const updateManySecretsRaw = async ({
|
||||
actorId,
|
||||
projectSlug,
|
||||
projectId: optionalProjectId,
|
||||
environment,
|
||||
actor,
|
||||
actorOrgId,
|
||||
@@ -1340,9 +1374,15 @@ export const secretServiceFactory = ({
|
||||
secretPath,
|
||||
secrets: inputSecrets = []
|
||||
}: TUpdateManySecretRawDTO) => {
|
||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||
const projectId = project.id;
|
||||
if (!projectSlug && !optionalProjectId)
|
||||
throw new BadRequestError({ message: "Must provide either project slug or projectId" });
|
||||
|
||||
let projectId = optionalProjectId as string;
|
||||
if (!optionalProjectId && projectSlug) {
|
||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||
projectId = project.id;
|
||||
}
|
||||
|
||||
const botKey = await projectBotService.getBotKey(projectId);
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
@@ -1355,25 +1395,40 @@ export const secretServiceFactory = ({
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
secrets: inputSecrets.map(({ secretComment, secretKey, secretValue, skipMultilineEncoding }) => {
|
||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretKey, botKey);
|
||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||
return {
|
||||
secretName: secretKey,
|
||||
type: SecretType.Shared,
|
||||
secrets: inputSecrets.map(
|
||||
({
|
||||
secretComment,
|
||||
secretKey,
|
||||
secretValue,
|
||||
skipMultilineEncoding,
|
||||
secretKeyCiphertext: secretKeyEncrypted.ciphertext,
|
||||
secretKeyIV: secretKeyEncrypted.iv,
|
||||
secretKeyTag: secretKeyEncrypted.tag,
|
||||
secretValueCiphertext: secretValueEncrypted.ciphertext,
|
||||
secretValueIV: secretValueEncrypted.iv,
|
||||
secretValueTag: secretValueEncrypted.tag,
|
||||
secretCommentCiphertext: secretCommentEncrypted.ciphertext,
|
||||
secretCommentIV: secretCommentEncrypted.iv,
|
||||
secretCommentTag: secretCommentEncrypted.tag
|
||||
};
|
||||
})
|
||||
tagIds: tags,
|
||||
newSecretName,
|
||||
secretReminderNote,
|
||||
secretReminderRepeatDays
|
||||
}) => {
|
||||
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(newSecretName || secretKey, botKey);
|
||||
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
|
||||
const secretCommentEncrypted = encryptSymmetric128BitHexKeyUTF8(secretComment || "", botKey);
|
||||
return {
|
||||
secretName: secretKey,
|
||||
newSecretName,
|
||||
tags,
|
||||
secretReminderRepeatDays,
|
||||
secretReminderNote,
|
||||
type: SecretType.Shared,
|
||||
skipMultilineEncoding,
|
||||
secretKeyCiphertext: secretKeyEncrypted.ciphertext,
|
||||
secretKeyIV: secretKeyEncrypted.iv,
|
||||
secretKeyTag: secretKeyEncrypted.tag,
|
||||
secretValueCiphertext: secretValueEncrypted.ciphertext,
|
||||
secretValueIV: secretValueEncrypted.iv,
|
||||
secretValueTag: secretValueEncrypted.tag,
|
||||
secretCommentCiphertext: secretCommentEncrypted.ciphertext,
|
||||
secretCommentIV: secretCommentEncrypted.iv,
|
||||
secretCommentTag: secretCommentEncrypted.tag
|
||||
};
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
return secrets.map((secret) =>
|
||||
@@ -1384,6 +1439,7 @@ export const secretServiceFactory = ({
|
||||
const deleteManySecretsRaw = async ({
|
||||
actorId,
|
||||
projectSlug,
|
||||
projectId: optionalProjectId,
|
||||
environment,
|
||||
actor,
|
||||
actorOrgId,
|
||||
@@ -1391,9 +1447,15 @@ export const secretServiceFactory = ({
|
||||
secretPath,
|
||||
secrets: inputSecrets = []
|
||||
}: TDeleteManySecretRawDTO) => {
|
||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||
const projectId = project.id;
|
||||
if (!projectSlug && !optionalProjectId)
|
||||
throw new BadRequestError({ message: "Must provide either project slug or projectId" });
|
||||
|
||||
let projectId = optionalProjectId as string;
|
||||
if (!optionalProjectId && projectSlug) {
|
||||
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||
projectId = project.id;
|
||||
}
|
||||
|
||||
const botKey = await projectBotService.getBotKey(projectId);
|
||||
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
|
||||
@@ -1406,7 +1468,7 @@ export const secretServiceFactory = ({
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
secrets: inputSecrets.map(({ secretKey }) => ({ secretName: secretKey, type: SecretType.Shared }))
|
||||
secrets: inputSecrets.map(({ secretKey, type = SecretType.Shared }) => ({ secretName: secretKey, type }))
|
||||
});
|
||||
|
||||
return secrets.map((secret) =>
|
||||
|
||||
@@ -160,14 +160,16 @@ export type TGetASecretRawDTO = {
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TCreateSecretRawDTO = TProjectPermission & {
|
||||
secretName: string;
|
||||
secretPath: string;
|
||||
environment: string;
|
||||
secretName: string;
|
||||
secretValue: string;
|
||||
type: SecretType;
|
||||
tagIds?: string[];
|
||||
secretComment?: string;
|
||||
skipMultilineEncoding?: boolean;
|
||||
secretReminderRepeatDays?: number | null;
|
||||
secretReminderNote?: string | null;
|
||||
};
|
||||
|
||||
export type TUpdateSecretRawDTO = TProjectPermission & {
|
||||
@@ -175,11 +177,16 @@ export type TUpdateSecretRawDTO = TProjectPermission & {
|
||||
environment: string;
|
||||
secretName: string;
|
||||
secretValue?: string;
|
||||
newSecretName?: string;
|
||||
secretComment?: string;
|
||||
type: SecretType;
|
||||
tagIds?: string[];
|
||||
skipMultilineEncoding?: boolean;
|
||||
secretReminderRepeatDays?: number | null;
|
||||
secretReminderNote?: string | null;
|
||||
metadata?: {
|
||||
source?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type TDeleteSecretRawDTO = TProjectPermission & {
|
||||
@@ -191,34 +198,46 @@ export type TDeleteSecretRawDTO = TProjectPermission & {
|
||||
|
||||
export type TCreateManySecretRawDTO = Omit<TProjectPermission, "projectId"> & {
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
projectId?: string;
|
||||
projectSlug?: string;
|
||||
environment: string;
|
||||
secrets: {
|
||||
secretKey: string;
|
||||
secretValue: string;
|
||||
secretComment?: string;
|
||||
skipMultilineEncoding?: boolean;
|
||||
tagIds?: string[];
|
||||
metadata?: {
|
||||
source?: string;
|
||||
};
|
||||
}[];
|
||||
};
|
||||
|
||||
export type TUpdateManySecretRawDTO = Omit<TProjectPermission, "projectId"> & {
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
projectId?: string;
|
||||
projectSlug?: string;
|
||||
environment: string;
|
||||
secrets: {
|
||||
secretKey: string;
|
||||
newSecretName?: string;
|
||||
secretValue: string;
|
||||
secretComment?: string;
|
||||
skipMultilineEncoding?: boolean;
|
||||
tagIds?: string[];
|
||||
secretReminderRepeatDays?: number | null;
|
||||
secretReminderNote?: string | null;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type TDeleteManySecretRawDTO = Omit<TProjectPermission, "projectId"> & {
|
||||
secretPath: string;
|
||||
projectSlug: string;
|
||||
projectId?: string;
|
||||
projectSlug?: string;
|
||||
environment: string;
|
||||
secrets: {
|
||||
secretKey: string;
|
||||
type?: SecretType;
|
||||
}[];
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user