feat: changed line length to 120

This commit is contained in:
Akhil Mohan
2024-01-30 22:40:10 +05:30
parent 5855cc660a
commit bcbb49ed1b
142 changed files with 1183 additions and 3706 deletions
+5 -24
View File
@@ -11,17 +11,9 @@ export type TSecretDALFactory = ReturnType<typeof secretDALFactory>;
export const secretDALFactory = (db: TDbClient) => {
const secretOrm = ormify(db, TableName.Secret);
const update = async (
filter: Partial<TSecrets>,
data: Omit<TSecretsUpdate, "version">,
tx?: Knex
) => {
const update = async (filter: Partial<TSecrets>, data: Omit<TSecretsUpdate, "version">, tx?: Knex) => {
try {
const sec = await (tx || db)(TableName.Secret)
.where(filter)
.update(data)
.increment("version", 1)
.returning("*");
const sec = await (tx || db)(TableName.Secret).where(filter).update(data).increment("version", 1).returning("*");
return sec;
} catch (error) {
throw new DatabaseError({ error, name: "update secret" });
@@ -30,10 +22,7 @@ export const secretDALFactory = (db: TDbClient) => {
// the idea is to use postgres specific function
// insert with id this will cause a conflict then merge the data
const bulkUpdate = async (
data: Array<{ filter: Partial<TSecrets>; data: TSecretsUpdate }>,
tx?: Knex
) => {
const bulkUpdate = async (data: Array<{ filter: Partial<TSecrets>; data: TSecretsUpdate }>, tx?: Knex) => {
try {
const secs = await Promise.all(
data.map(async ({ filter, data: updateData }) => {
@@ -91,16 +80,8 @@ export const secretDALFactory = (db: TDbClient) => {
.where((bd) => {
void bd.whereNull("userId").orWhere({ userId: userId || null });
})
.leftJoin(
TableName.JnSecretTag,
`${TableName.Secret}.id`,
`${TableName.JnSecretTag}.${TableName.Secret}Id`
)
.leftJoin(
TableName.SecretTag,
`${TableName.JnSecretTag}.${TableName.SecretTag}Id`,
`${TableName.SecretTag}.id`
)
.leftJoin(TableName.JnSecretTag, `${TableName.Secret}.id`, `${TableName.JnSecretTag}.${TableName.Secret}Id`)
.leftJoin(TableName.SecretTag, `${TableName.JnSecretTag}.${TableName.SecretTag}Id`, `${TableName.SecretTag}.id`)
.select(selectAllTableCols(TableName.Secret))
.select(db.ref("id").withSchema(TableName.SecretTag).as("tagId"))
.select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor"))
+3 -14
View File
@@ -8,10 +8,7 @@ import { buildSecretBlindIndexFromName, decryptSymmetric128BitHexKeyUTF8 } from
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
import { TSecretDALFactory } from "./secret-dal";
export const generateSecretBlindIndexBySalt = async (
secretName: string,
secretBlindIndexDoc: TSecretBlindIndexes
) => {
export const generateSecretBlindIndexBySalt = async (secretName: string, secretBlindIndexDoc: TSecretBlindIndexes) => {
const appCfg = getConfig();
const secretBlindIndex = await buildSecretBlindIndexFromName({
secretName,
@@ -32,12 +29,7 @@ type TInterpolateSecretArg = {
folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath">;
};
export const interpolateSecrets = ({
projectId,
secretEncKey,
secretDAL,
folderDAL
}: TInterpolateSecretArg) => {
export const interpolateSecrets = ({ projectId, secretEncKey, secretDAL, folderDAL }: TInterpolateSecretArg) => {
const fetchSecretsCrossEnv = () => {
const fetchCache: Record<string, Record<string, string>> = {};
@@ -197,10 +189,7 @@ export const interpolateSecrets = ({
return expandSecrets;
};
export const decryptSecretRaw = (
secret: TSecrets & { workspace: string; environment: string },
key: string
) => {
export const decryptSecretRaw = (secret: TSecrets & { workspace: string; environment: string }, key: string) => {
const secretKey = decryptSymmetric128BitHexKeyUTF8({
ciphertext: secret.secretKeyCiphertext,
iv: secret.secretKeyIV,
+11 -39
View File
@@ -23,11 +23,7 @@ import { TWebhookDALFactory } from "../webhook/webhook-dal";
import { fnTriggerWebhook } from "../webhook/webhook-fns";
import { TSecretDALFactory } from "./secret-dal";
import { interpolateSecrets } from "./secret-fns";
import {
TCreateSecretReminderDTO,
THandleReminderDTO,
TRemoveSecretReminderDTO
} from "./secret-types";
import { TCreateSecretReminderDTO, THandleReminderDTO, TRemoveSecretReminderDTO } from "./secret-types";
export type TSecretQueueFactory = ReturnType<typeof secretQueueFactory>;
@@ -105,20 +101,13 @@ export const secretQueueFactory = ({
QueueJobs.SecretReminder,
{
// on prod it this will be in days, in development this will be second
every:
appCfg.NODE_ENV === "development"
? secondsToMillis(dto.repeatDays)
: daysToMillisecond(dto.repeatDays)
every: appCfg.NODE_ENV === "development" ? secondsToMillis(dto.repeatDays) : daysToMillisecond(dto.repeatDays)
},
`reminder-${dto.secretId}`
);
};
const addSecretReminder = async ({
oldSecret,
newSecret,
projectId
}: TCreateSecretReminderDTO) => {
const addSecretReminder = async ({ oldSecret, newSecret, projectId }: TCreateSecretReminderDTO) => {
try {
const appCfg = getConfig();
@@ -179,8 +168,7 @@ export const secretQueueFactory = ({
if (newSecret.type !== "personal" && secretReminderRepeatDays !== undefined) {
if (
(secretReminderRepeatDays &&
oldSecret.secretReminderRepeatDays !== secretReminderRepeatDays) ||
(secretReminderRepeatDays && oldSecret.secretReminderRepeatDays !== secretReminderRepeatDays) ||
(secretReminderNote && oldSecret.secretReminderNote !== secretReminderNote)
) {
await addSecretReminder({
@@ -212,10 +200,7 @@ export const secretQueueFactory = ({
secretDAL,
folderDAL
});
const content: Record<
string,
{ value: string; comment?: string; skipMultilineEncoding?: boolean }
> = {};
const content: Record<string, { value: string; comment?: string; skipMultilineEncoding?: boolean }> = {};
importedSecrets.forEach(({ secrets: secs }) => {
secs.forEach((secret) => {
@@ -294,8 +279,7 @@ export const secretQueueFactory = ({
const integrations = await integrationDAL.findByProjectIdV2(projectId, environment);
const toBeSyncedIntegrations = integrations.filter(
({ secretPath: integrationSecPath, isActive }) =>
isActive && isSamePath(secretPath, integrationSecPath)
({ secretPath: integrationSecPath, isActive }) => isActive && isSamePath(secretPath, integrationSecPath)
);
if (!integrations.length) return;
@@ -309,14 +293,8 @@ export const secretQueueFactory = ({
};
const botKey = await projectBotService.getBotKey(projectId);
const { accessToken, accessId } = await integrationAuthService.getIntegrationAccessToken(
integrationAuth,
botKey
);
const secrets = await getIntegrationSecrets(
{ environment, projectId, secretPath, folderId: folder.id },
botKey
);
const { accessToken, accessId } = await integrationAuthService.getIntegrationAccessToken(integrationAuth, botKey);
const secrets = await getIntegrationSecrets({ environment, projectId, secretPath, folderId: folder.id }, botKey);
const suffixedSecrets: typeof secrets = {};
const metadata = integration.metadata as Record<string, string>;
if (metadata) {
@@ -353,25 +331,19 @@ export const secretQueueFactory = ({
const project = await projectDAL.findById(projectId);
if (!organization) {
logger.info(
`secretReminderQueue.process: [secretDocument=${data.secretId}] no organization found`
);
logger.info(`secretReminderQueue.process: [secretDocument=${data.secretId}] no organization found`);
return;
}
if (!project) {
logger.info(
`secretReminderQueue.process: [secretDocument=${data.secretId}] no project found`
);
logger.info(`secretReminderQueue.process: [secretDocument=${data.secretId}] no project found`);
return;
}
const projectMembers = await projectMembershipDAL.findAllProjectMembers(projectId);
if (!projectMembers || !projectMembers.length) {
logger.info(
`secretReminderQueue.process: [secretDocument=${data.secretId}] no project members found`
);
logger.info(`secretReminderQueue.process: [secretDocument=${data.secretId}] no project members found`);
return;
}
+39 -159
View File
@@ -1,17 +1,8 @@
import { ForbiddenError, subject } from "@casl/ability";
import {
SecretEncryptionAlgo,
SecretKeyEncoding,
SecretsSchema,
SecretType,
TableName
} from "@app/db/schemas";
import { SecretEncryptionAlgo, SecretKeyEncoding, SecretsSchema, SecretType, TableName } from "@app/db/schemas";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import {
ProjectPermissionActions,
ProjectPermissionSub
} from "@app/ee/services/permission/project-permission";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service";
import { getConfig } from "@app/lib/config/env";
import { buildSecretBlindIndexFromName, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
@@ -58,17 +49,11 @@ type TSecretServiceFactoryDep = {
secretDAL: TSecretDALFactory;
secretTagDAL: TSecretTagDALFactory;
secretVersionDAL: TSecretVersionDALFactory;
folderDAL: Pick<
TSecretFolderDALFactory,
"findBySecretPath" | "updateById" | "findById" | "findByManySecretPath"
>;
folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath" | "updateById" | "findById" | "findByManySecretPath">;
secretBlindIndexDAL: TSecretBlindIndexDALFactory;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
snapshotService: Pick<TSecretSnapshotServiceFactory, "performSnapshot">;
secretQueueService: Pick<
TSecretQueueFactory,
"syncSecrets" | "handleSecretReminder" | "removeSecretReminder"
>;
secretQueueService: Pick<TSecretQueueFactory, "syncSecrets" | "handleSecretReminder" | "removeSecretReminder">;
projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">;
secretImportDAL: Pick<TSecretImportDALFactory, "find">;
secretVersionTagDAL: Pick<TSecretVersionTagDALFactory, "insertMany">;
@@ -93,8 +78,7 @@ export const secretServiceFactory = ({
const appCfg = getConfig();
const secretBlindIndexDoc = await secretBlindIndexDAL.findOne({ projectId });
if (!secretBlindIndexDoc)
throw new BadRequestError({ message: "Blind index not found", name: "Create secret" });
if (!secretBlindIndexDoc) throw new BadRequestError({ message: "Blind index not found", name: "Create secret" });
const secretBlindIndex = await buildSecretBlindIndexFromName({
secretName,
@@ -116,15 +100,11 @@ export const secretServiceFactory = ({
inputSecrets.map(({ tags, ...el }) => ({ ...el, folderId })),
tx
);
const newSecretGroupByBlindIndex = groupBy(
newSecrets,
(item) => item.secretBlindIndex as string
);
const newSecretGroupByBlindIndex = groupBy(newSecrets, (item) => item.secretBlindIndex as string);
const newSecretTags = inputSecrets.flatMap(({ tags: secretTags = [], secretBlindIndex }) =>
secretTags.map((tag) => ({
[`${TableName.SecretTag}Id` as const]: tag,
[`${TableName.Secret}Id` as const]:
newSecretGroupByBlindIndex[secretBlindIndex as string][0].id
[`${TableName.Secret}Id` as const]: newSecretGroupByBlindIndex[secretBlindIndex as string][0].id
}))
);
const secretVersions = await secretVersionDAL.insertMany(
@@ -148,12 +128,7 @@ export const secretServiceFactory = ({
return newSecrets.map((secret) => ({ ...secret, _id: secret.id }));
};
const fnSecretBulkUpdate = async ({
tx,
inputSecrets,
folderId,
projectId
}: TFnSecretBulkUpdate) => {
const fnSecretBulkUpdate = async ({ tx, inputSecrets, folderId, projectId }: TFnSecretBulkUpdate) => {
const newSecrets = await secretDAL.bulkUpdate(
inputSecrets.map(({ filter, data: { tags, ...data } }) => ({
filter: { ...filter, folderId },
@@ -197,12 +172,7 @@ export const secretServiceFactory = ({
return newSecrets.map((secret) => ({ ...secret, _id: secret.id }));
};
const fnSecretBulkDelete = async ({
folderId,
inputSecrets,
tx,
actorId
}: TFnSecretBulkDelete) => {
const fnSecretBulkDelete = async ({ folderId, inputSecrets, tx, actorId }: TFnSecretBulkDelete) => {
const deletedSecrets = await secretDAL.deleteMany(
inputSecrets.map(({ type, secretBlindIndex }) => ({
blindIndex: secretBlindIndex,
@@ -245,9 +215,7 @@ export const secretServiceFactory = ({
}: TFnSecretBlindIndexCheck) => {
const blindIndex2KeyName: Record<string, string> = {}; // used at audit log point
const keyName2BlindIndex = await Promise.all(
inputSecrets.map(({ secretName }) =>
generateSecretBlindIndexBySalt(secretName, blindIndexCfg)
)
inputSecrets.map(({ secretName }) => generateSecretBlindIndexBySalt(secretName, blindIndexCfg))
).then((blindIndexes) =>
blindIndexes.reduce<Record<string, string>>((prev, curr, i) => {
// eslint-disable-next-line
@@ -282,11 +250,7 @@ export const secretServiceFactory = ({
// this is used when secret blind index already exist
// mainly for secret approval
const fnSecretBlindIndexCheckV2 = async ({
inputSecrets,
folderId,
userId
}: TFnSecretBlindIndexCheckV2) => {
const fnSecretBlindIndexCheckV2 = async ({ inputSecrets, folderId, userId }: TFnSecretBlindIndexCheckV2) => {
if (inputSecrets.some(({ type }) => type === SecretType.Personal) && !userId) {
throw new BadRequestError({ message: "Missing user id for personal secret" });
}
@@ -303,14 +267,7 @@ export const secretServiceFactory = ({
return { secsGroupedByBlindIndex, secrets };
};
const createSecret = async ({
path,
actor,
actorId,
environment,
projectId,
...inputSecret
}: TCreateSecretDTO) => {
const createSecret = async ({ path, actor, actorId, environment, projectId, ...inputSecret }: TCreateSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create,
@@ -322,8 +279,7 @@ export const secretServiceFactory = ({
const folderId = folder.id;
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg)
throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" });
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" });
if (ActorType.USER !== actor && inputSecret.type === SecretType.Personal) {
throw new BadRequestError({ message: "Must be user to create personal secret" });
@@ -352,11 +308,8 @@ export const secretServiceFactory = ({
// validate tags
// fetch all tags and if not same count throw error meaning one was invalid tags
const tags = inputSecret.tags
? await secretTagDAL.findManyTagsById(projectId, inputSecret.tags)
: [];
if ((inputSecret.tags || []).length !== tags.length)
throw new BadRequestError({ message: "Tag not found" });
const tags = inputSecret.tags ? await secretTagDAL.findManyTagsById(projectId, inputSecret.tags) : [];
if ((inputSecret.tags || []).length !== tags.length) throw new BadRequestError({ message: "Tag not found" });
const { secretName, type, ...el } = inputSecret;
const secret = await secretDAL.transaction((tx) =>
@@ -384,14 +337,7 @@ export const secretServiceFactory = ({
return { ...secret[0], environment, workspace: projectId, tags };
};
const updateSecret = async ({
path,
actor,
actorId,
environment,
projectId,
...inputSecret
}: TUpdateSecretDTO) => {
const updateSecret = async ({ path, actor, actorId, environment, projectId, ...inputSecret }: TUpdateSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
@@ -403,8 +349,7 @@ export const secretServiceFactory = ({
const folderId = folder.id;
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg)
throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" });
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" });
if (ActorType.USER !== actor && inputSecret.type === SecretType.Personal) {
throw new BadRequestError({ message: "Must be user to create personal secret" });
@@ -441,11 +386,8 @@ export const secretServiceFactory = ({
projectId
});
const tags = inputSecret.tags
? await secretTagDAL.findManyTagsById(projectId, inputSecret.tags)
: [];
if ((inputSecret.tags || []).length !== tags.length)
throw new BadRequestError({ message: "Tag not found" });
const tags = inputSecret.tags ? await secretTagDAL.findManyTagsById(projectId, inputSecret.tags) : [];
if ((inputSecret.tags || []).length !== tags.length) throw new BadRequestError({ message: "Tag not found" });
const { secretName, ...el } = inputSecret;
const updatedSecret = await secretDAL.transaction(async (tx) =>
@@ -487,14 +429,7 @@ export const secretServiceFactory = ({
return { ...updatedSecret[0], workspace: projectId, environment };
};
const deleteSecret = async ({
path,
actor,
actorId,
environment,
projectId,
...inputSecret
}: TDeleteSecretDTO) => {
const deleteSecret = async ({ path, actor, actorId, environment, projectId, ...inputSecret }: TDeleteSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete,
@@ -506,8 +441,7 @@ export const secretServiceFactory = ({
const folderId = folder.id;
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg)
throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" });
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "CreateSecret" });
if (ActorType.USER !== actor && inputSecret.type === SecretType.Personal) {
throw new BadRequestError({ message: "Must be user to create personal secret" });
@@ -542,14 +476,7 @@ export const secretServiceFactory = ({
return { ...deletedSecret[0], _id: deletedSecret[0].id, workspace: projectId, environment };
};
const getSecrets = async ({
actorId,
path,
environment,
projectId,
actor,
includeImports
}: TGetSecretsDTO) => {
const getSecrets = async ({ actorId, path, environment, projectId, actor, includeImports }: TGetSecretsDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
@@ -683,8 +610,7 @@ export const secretServiceFactory = ({
const folderId = folder.id;
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg)
throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
const { keyName2BlindIndex } = await fnSecretBlindIndexCheck({
inputSecrets,
@@ -738,8 +664,7 @@ export const secretServiceFactory = ({
const folderId = folder.id;
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg)
throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
const { keyName2BlindIndex } = await fnSecretBlindIndexCheck({
inputSecrets,
@@ -809,8 +734,7 @@ export const secretServiceFactory = ({
const folderId = folder.id;
const blindIndexCfg = await secretBlindIndexDAL.findOne({ projectId });
if (!blindIndexCfg)
throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
if (!blindIndexCfg) throw new BadRequestError({ message: "Blind index not found", name: "Update secret" });
const { keyName2BlindIndex } = await fnSecretBlindIndexCheck({
inputSecrets,
@@ -838,46 +762,22 @@ export const secretServiceFactory = ({
return secretsDeleted;
};
const listSecretVersionsBySecretId = async ({
actorId,
actor,
limit,
offset,
secretId
}: TListSecretVersionDTO) => {
const listSecretVersionsBySecretId = async ({ actorId, actor, limit, offset, secretId }: TListSecretVersionDTO) => {
const secret = await secretDAL.findById(secretId);
if (!secret) throw new BadRequestError({ message: "Failed to find secret" });
const folder = await folderDAL.findById(secret.folderId);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
folder.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.SecretRollback
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, folder.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
const secretVersions = await secretVersionDAL.find(
{ secretId },
{ limit, offset, sort: [["createdAt", "desc"]] }
);
const secretVersions = await secretVersionDAL.find({ secretId }, { limit, offset, sort: [["createdAt", "desc"]] });
return secretVersions;
};
const getSecretsRaw = async ({
projectId,
path,
actor,
actorId,
environment,
includeImports
}: TGetSecretsRawDTO) => {
const getSecretsRaw = async ({ projectId, path, actor, actorId, environment, includeImports }: TGetSecretsRawDTO) => {
const botKey = await projectBotService.getBotKey(projectId);
if (!botKey)
throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
const { secrets, imports } = await getSecrets({
actorId,
@@ -911,8 +811,7 @@ export const secretServiceFactory = ({
version
}: TGetASecretRawDTO) => {
const botKey = await projectBotService.getBotKey(projectId);
if (!botKey)
throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
const secret = await getSecretByName({
actorId,
@@ -941,8 +840,7 @@ export const secretServiceFactory = ({
skipMultilineEncoding
}: TCreateSecretRawDTO) => {
const botKey = await projectBotService.getBotKey(projectId);
if (!botKey)
throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
const secretKeyEncrypted = encryptSymmetric128BitHexKeyUTF8(secretName, botKey);
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
@@ -986,8 +884,7 @@ export const secretServiceFactory = ({
skipMultilineEncoding
}: TUpdateSecretRawDTO) => {
const botKey = await projectBotService.getBotKey(projectId);
if (!botKey)
throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
const secretValueEncrypted = encryptSymmetric128BitHexKeyUTF8(secretValue || "", botKey);
@@ -1021,8 +918,7 @@ export const secretServiceFactory = ({
secretPath
}: TDeleteSecretRawDTO) => {
const botKey = await projectBotService.getBotKey(projectId);
if (!botKey)
throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
const secret = await deleteSecret({
secretName,
@@ -1040,33 +936,17 @@ export const secretServiceFactory = ({
return decryptSecretRaw(secret, botKey);
};
const getSecretVersions = async ({
actorId,
actor,
limit = 20,
offset = 0,
secretId
}: TGetSecretVersionsDTO) => {
const getSecretVersions = async ({ actorId, actor, limit = 20, offset = 0, secretId }: TGetSecretVersionsDTO) => {
const secret = await secretDAL.findById(secretId);
if (!secret) throw new BadRequestError({ message: "Failed to find secret" });
const folder = await folderDAL.findById(secret.folderId);
if (!folder) throw new BadRequestError({ message: "Failed to find secret" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
folder.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.SecretRollback
);
const { permission } = await permissionService.getProjectPermission(actor, actorId, folder.projectId);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
const secretVersions = await secretVersionDAL.find(
{ secretId },
{ offset, limit, sort: [["createdAt", "desc"]] }
);
const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] });
return secretVersions;
};
+2 -11
View File
@@ -1,20 +1,11 @@
import { Knex } from "knex";
import {
SecretType,
TSecretBlindIndexes,
TSecrets,
TSecretsInsert,
TSecretsUpdate
} from "@app/db/schemas";
import { SecretType, TSecretBlindIndexes, TSecrets, TSecretsInsert, TSecretsUpdate } from "@app/db/schemas";
import { TProjectPermission } from "@app/lib/types";
type TPartialSecret = Pick<TSecrets, "id" | "secretReminderRepeatDays" | "secretReminderNote">;
type TPartialInputSecret = Pick<
TSecrets,
"type" | "secretReminderNote" | "secretReminderRepeatDays" | "id"
>;
type TPartialInputSecret = Pick<TSecrets, "type" | "secretReminderNote" | "secretReminderRepeatDays" | "id">;
export type TCreateSecretDTO = {
secretName: string;
@@ -38,17 +38,11 @@ export const secretVersionDALFactory = (db: TDbClient) => {
const findLatestVersionMany = async (folderId: string, secretIds: string[], tx?: Knex) => {
try {
const docs: Array<TSecretVersions & { max: number }> = await (tx || db)(
TableName.SecretVersion
)
const docs: Array<TSecretVersions & { max: number }> = await (tx || db)(TableName.SecretVersion)
.where("folderId", folderId)
.whereIn(`${TableName.SecretVersion}.secretId`, secretIds)
.join(
(tx || db)(TableName.SecretVersion)
.groupBy("secretId")
.max("version")
.select("secretId")
.as("latestVersion"),
(tx || db)(TableName.SecretVersion).groupBy("secretId").max("version").select("secretId").as("latestVersion"),
(bd) => {
bd.on(`${TableName.SecretVersion}.secretId`, "latestVersion.secretId").andOn(
`${TableName.SecretVersion}.version`,