requested changes

This commit is contained in:
Daniel Hougaard
2025-03-07 19:26:18 +04:00
parent 50610945be
commit 77431b4719
5 changed files with 64 additions and 70 deletions
-1
View File
@@ -1073,7 +1073,6 @@ export const registerRoutes = async (
const secretService = secretServiceFactory({ const secretService = secretServiceFactory({
folderDAL, folderDAL,
secretVersionDAL, secretVersionDAL,
secretV2BridgeDAL,
secretVersionTagDAL, secretVersionTagDAL,
secretBlindIndexDAL, secretBlindIndexDAL,
permissionService, permissionService,
@@ -962,20 +962,23 @@ export const secretV2BridgeServiceFactory = ({
}; };
}; };
const getSecretById = async ({ actorId, actor, actorOrgId, actorAuthMethod, secret }: TGetASecretByIdDTO) => { const getSecretById = async ({ actorId, actor, actorOrgId, actorAuthMethod, secretId }: TGetASecretByIdDTO) => {
const folder = await folderDAL.findById(secret.folderId); const secret = await secretDAL.findOneWithTags({
if (!folder) { id: secretId
});
if (!secret) {
throw new NotFoundError({ throw new NotFoundError({
message: `Folder with id '${secret.folderId}' not found`, message: `Secret with ID '${secretId}' not found`,
name: "GetSecretById" name: "GetSecretById"
}); });
} }
const [folderWithPath] = await folderDAL.findSecretPathByFolderIds(folder.projectId, [folder.id]); const [folderWithPath] = await folderDAL.findSecretPathByFolderIds(secret.projectId, [secret.folderId]);
if (!folderWithPath) { if (!folderWithPath) {
throw new NotFoundError({ throw new NotFoundError({
message: `Folder with id '${folder.id}' not found`, message: `Folder with id '${secret.folderId}' not found`,
name: "GetSecretById" name: "GetSecretById"
}); });
} }
@@ -983,7 +986,7 @@ export const secretV2BridgeServiceFactory = ({
const { permission } = await permissionService.getProjectPermission({ const { permission } = await permissionService.getProjectPermission({
actor, actor,
actorId, actorId,
projectId: folder.projectId, projectId: secret.projectId,
actorAuthMethod, actorAuthMethod,
actorOrgId, actorOrgId,
actionProjectType: ActionProjectType.SecretManager actionProjectType: ActionProjectType.SecretManager
@@ -992,7 +995,7 @@ export const secretV2BridgeServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { subject(ProjectPermissionSub.Secrets, {
environment: folder.environment.envSlug, environment: folderWithPath.environmentSlug,
secretPath: folderWithPath.path, secretPath: folderWithPath.path,
secretName: secret.key, secretName: secret.key,
secretTags: secret.tags.map((i) => i.slug) secretTags: secret.tags.map((i) => i.slug)
@@ -1008,7 +1011,7 @@ export const secretV2BridgeServiceFactory = ({
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.SecretManager, type: KmsDataKey.SecretManager,
projectId: folder.projectId projectId: secret.projectId
}); });
const secretValue = secret.encryptedValue const secretValue = secret.encryptedValue
@@ -1019,7 +1022,7 @@ export const secretV2BridgeServiceFactory = ({
? secretManagerDecryptor({ cipherTextBlob: secret.encryptedComment }).toString() ? secretManagerDecryptor({ cipherTextBlob: secret.encryptedComment }).toString()
: ""; : "";
return reshapeBridgeSecret(folder.projectId, folder.environment.envSlug, folderWithPath.path, { return reshapeBridgeSecret(secret.projectId, folderWithPath.environmentSlug, folderWithPath.path, {
...secret, ...secret,
value: secretValue, value: secretValue,
comment: secretComment comment: secretComment
+8 -30
View File
@@ -9,8 +9,7 @@ import {
SecretEncryptionAlgo, SecretEncryptionAlgo,
SecretKeyEncoding, SecretKeyEncoding,
SecretsSchema, SecretsSchema,
SecretType, SecretType
TableName
} from "@app/db/schemas"; } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
@@ -45,7 +44,6 @@ import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
import { TSecretImportDALFactory } from "../secret-import/secret-import-dal"; import { TSecretImportDALFactory } from "../secret-import/secret-import-dal";
import { fnSecretsFromImports } from "../secret-import/secret-import-fns"; import { fnSecretsFromImports } from "../secret-import/secret-import-fns";
import { TSecretTagDALFactory } from "../secret-tag/secret-tag-dal"; import { TSecretTagDALFactory } from "../secret-tag/secret-tag-dal";
import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal";
import { TSecretV2BridgeServiceFactory } from "../secret-v2-bridge/secret-v2-bridge-service"; import { TSecretV2BridgeServiceFactory } from "../secret-v2-bridge/secret-v2-bridge-service";
import { TGetSecretReferencesTreeDTO } from "../secret-v2-bridge/secret-v2-bridge-types"; import { TGetSecretReferencesTreeDTO } from "../secret-v2-bridge/secret-v2-bridge-types";
import { TSecretDALFactory } from "./secret-dal"; import { TSecretDALFactory } from "./secret-dal";
@@ -92,7 +90,6 @@ import { TSecretVersionTagDALFactory } from "./secret-version-tag-dal";
type TSecretServiceFactoryDep = { type TSecretServiceFactoryDep = {
secretDAL: TSecretDALFactory; secretDAL: TSecretDALFactory;
secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "findOneWithTags">;
secretTagDAL: TSecretTagDALFactory; secretTagDAL: TSecretTagDALFactory;
secretVersionDAL: TSecretVersionDALFactory; secretVersionDAL: TSecretVersionDALFactory;
projectDAL: Pick<TProjectDALFactory, "checkProjectUpgradeStatus" | "findProjectBySlug" | "findById">; projectDAL: Pick<TProjectDALFactory, "checkProjectUpgradeStatus" | "findProjectBySlug" | "findById">;
@@ -128,7 +125,6 @@ type TSecretServiceFactoryDep = {
export type TSecretServiceFactory = ReturnType<typeof secretServiceFactory>; export type TSecretServiceFactory = ReturnType<typeof secretServiceFactory>;
export const secretServiceFactory = ({ export const secretServiceFactory = ({
secretDAL, secretDAL,
secretV2BridgeDAL,
projectEnvDAL, projectEnvDAL,
secretTagDAL, secretTagDAL,
secretVersionDAL, secretVersionDAL,
@@ -1388,33 +1384,15 @@ export const secretServiceFactory = ({
}; };
const getSecretByIdRaw = async ({ secretId, actorId, actor, actorOrgId, actorAuthMethod }: TGetASecretByIdRawDTO) => { const getSecretByIdRaw = async ({ secretId, actorId, actor, actorOrgId, actorAuthMethod }: TGetASecretByIdRawDTO) => {
const sec = await secretV2BridgeDAL.findOneWithTags({ const secret = await secretV2BridgeService.getSecretById({
[`${TableName.SecretV2}.id` as "id"]: secretId secretId,
actorId,
actor,
actorOrgId,
actorAuthMethod
}); });
if (!sec) { return secret;
throw new NotFoundError({
message: `Secret with id '${secretId}' not found`,
name: "GetSecretById"
});
}
const { shouldUseSecretV2Bridge } = await projectBotService.getBotKey(sec.projectId);
if (shouldUseSecretV2Bridge) {
const secret = await secretV2BridgeService.getSecretById({
secret: sec,
actorId,
actor,
actorOrgId,
actorAuthMethod
});
return secret;
}
throw new BadRequestError({
message: "Project version not supported. Please upgrade your project."
});
}; };
const getSecretByNameRaw = async ({ const getSecretByNameRaw = async ({
+2 -9
View File
@@ -1,7 +1,7 @@
import { Knex } from "knex"; import { Knex } from "knex";
import { z } from "zod"; import { z } from "zod";
import { SecretType, TSecretBlindIndexes, TSecrets, TSecretsInsert, TSecretsUpdate, TSecretsV2 } from "@app/db/schemas"; import { SecretType, TSecretBlindIndexes, TSecrets, TSecretsInsert, TSecretsUpdate } from "@app/db/schemas";
import { OrderByDirection, TProjectPermission } from "@app/lib/types"; import { OrderByDirection, TProjectPermission } from "@app/lib/types";
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
import { TProjectBotDALFactory } from "@app/services/project-bot/project-bot-dal"; import { TProjectBotDALFactory } from "@app/services/project-bot/project-bot-dal";
@@ -122,14 +122,7 @@ export type TGetASecretDTO = {
} & TProjectPermission; } & TProjectPermission;
export type TGetASecretByIdDTO = { export type TGetASecretByIdDTO = {
secret: TSecretsV2 & { secretId: string;
tags: {
id: string;
color?: string | null;
slug: string;
name: string;
}[];
};
} & Omit<TProjectPermission, "projectId">; } & Omit<TProjectPermission, "projectId">;
export type TCreateBulkSecretDTO = { export type TCreateBulkSecretDTO = {
@@ -5,6 +5,7 @@ import {
faArrowRotateRight, faArrowRotateRight,
faCheckCircle, faCheckCircle,
faClock, faClock,
faCopy,
faDesktop, faDesktop,
faEyeSlash, faEyeSlash,
faPlus, faPlus,
@@ -990,29 +991,49 @@ export const SecretDetailSidebar = ({
</Button> </Button>
)} )}
</ProjectPermissionCan> </ProjectPermissionCan>
<ProjectPermissionCan <div className="flex items-center gap-2">
I={ProjectPermissionActions.Delete} <Tooltip content="Copy Secret ID">
a={subject(ProjectPermissionSub.Secrets, {
environment,
secretPath,
secretName: secretKey,
secretTags: selectTagSlugs
})}
>
{(isAllowed) => (
<IconButton <IconButton
colorSchema="danger" variant="outline_bg"
ariaLabel="Delete Secret" ariaLabel="Copy Secret ID"
className="border border-mineshaft-600 bg-mineshaft-700 hover:border-red-500/70 hover:bg-red-600/20" onClick={async () => {
isDisabled={!isAllowed} await navigator.clipboard.writeText(secret.id);
onClick={onDeleteSecret}
createNotification({
title: "Secret ID Copied",
text: "The secret ID has been copied to your clipboard.",
type: "success"
});
}}
> >
<Tooltip content="Delete Secret"> <FontAwesomeIcon icon={faCopy} />
<FontAwesomeIcon icon={faTrash} />
</Tooltip>
</IconButton> </IconButton>
)} </Tooltip>
</ProjectPermissionCan> <ProjectPermissionCan
I={ProjectPermissionActions.Delete}
a={subject(ProjectPermissionSub.Secrets, {
environment,
secretPath,
secretName: secretKey,
secretTags: selectTagSlugs
})}
>
{(isAllowed) => (
<Tooltip content="Delete Secret">
<IconButton
colorSchema="danger"
variant="outline_bg"
ariaLabel="Delete Secret"
className="border border-mineshaft-600 bg-mineshaft-700 hover:border-red-500/70 hover:bg-red-600/20"
isDisabled={!isAllowed}
onClick={onDeleteSecret}
>
<FontAwesomeIcon icon={faTrash} />
</IconButton>
</Tooltip>
)}
</ProjectPermissionCan>
</div>
</div> </div>
</div> </div>
</div> </div>