mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 05:19:49 +00:00
feat: get secret by ID
This commit is contained in:
@@ -613,6 +613,9 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => {
|
||||
`${TableName.SecretV2JnTag}.${TableName.SecretTag}Id`,
|
||||
`${TableName.SecretTag}.id`
|
||||
)
|
||||
|
||||
.leftJoin(TableName.SecretFolder, `${TableName.SecretV2}.folderId`, `${TableName.SecretFolder}.id`)
|
||||
.leftJoin(TableName.Environment, `${TableName.SecretFolder}.envId`, `${TableName.Environment}.id`)
|
||||
.leftJoin(TableName.ResourceMetadata, `${TableName.SecretV2}.id`, `${TableName.ResourceMetadata}.secretId`)
|
||||
.select(selectAllTableCols(TableName.SecretV2))
|
||||
.select(db.ref("id").withSchema(TableName.SecretTag).as("tagId"))
|
||||
@@ -622,12 +625,13 @@ export const secretV2BridgeDALFactory = (db: TDbClient) => {
|
||||
db.ref("id").withSchema(TableName.ResourceMetadata).as("metadataId"),
|
||||
db.ref("key").withSchema(TableName.ResourceMetadata).as("metadataKey"),
|
||||
db.ref("value").withSchema(TableName.ResourceMetadata).as("metadataValue")
|
||||
);
|
||||
)
|
||||
.select(db.ref("projectId").withSchema(TableName.Environment).as("projectId"));
|
||||
|
||||
const docs = sqlNestRelationships({
|
||||
data: rawDocs,
|
||||
key: "id",
|
||||
parentMapper: (el) => ({ _id: el.id, ...SecretsV2Schema.parse(el) }),
|
||||
parentMapper: (el) => ({ _id: el.id, projectId: el.projectId, ...SecretsV2Schema.parse(el) }),
|
||||
childrenMapper: [
|
||||
{
|
||||
key: "tagId",
|
||||
|
||||
@@ -28,6 +28,7 @@ import { KmsDataKey } from "../kms/kms-types";
|
||||
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||
import { TResourceMetadataDALFactory } from "../resource-metadata/resource-metadata-dal";
|
||||
import { TSecretQueueFactory } from "../secret/secret-queue";
|
||||
import { TGetASecretByIdDTO } from "../secret/secret-types";
|
||||
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
|
||||
import { TSecretImportDALFactory } from "../secret-import/secret-import-dal";
|
||||
import { fnSecretsV2FromImports } from "../secret-import/secret-import-fns";
|
||||
@@ -73,7 +74,13 @@ type TSecretV2BridgeServiceFactoryDep = {
|
||||
projectEnvDAL: Pick<TProjectEnvDALFactory, "findOne" | "findBySlugs">;
|
||||
folderDAL: Pick<
|
||||
TSecretFolderDALFactory,
|
||||
"findBySecretPath" | "updateById" | "findById" | "findByManySecretPath" | "find" | "findBySecretPathMultiEnv"
|
||||
| "findBySecretPath"
|
||||
| "updateById"
|
||||
| "findById"
|
||||
| "findByManySecretPath"
|
||||
| "find"
|
||||
| "findBySecretPathMultiEnv"
|
||||
| "findSecretPathByFolderIds"
|
||||
>;
|
||||
secretImportDAL: Pick<TSecretImportDALFactory, "find" | "findByFolderIds">;
|
||||
secretQueueService: Pick<TSecretQueueFactory, "syncSecrets" | "handleSecretReminder" | "removeSecretReminder">;
|
||||
@@ -955,6 +962,70 @@ export const secretV2BridgeServiceFactory = ({
|
||||
};
|
||||
};
|
||||
|
||||
const getSecretById = async ({ actorId, actor, actorOrgId, actorAuthMethod, secret }: TGetASecretByIdDTO) => {
|
||||
const folder = await folderDAL.findById(secret.folderId);
|
||||
if (!folder) {
|
||||
throw new NotFoundError({
|
||||
message: `Folder with id '${secret.folderId}' not found`,
|
||||
name: "GetSecretById"
|
||||
});
|
||||
}
|
||||
|
||||
const [folderWithPath] = await folderDAL.findSecretPathByFolderIds(folder.projectId, [folder.id]);
|
||||
|
||||
if (!folderWithPath) {
|
||||
throw new NotFoundError({
|
||||
message: `Folder with id '${folder.id}' not found`,
|
||||
name: "GetSecretById"
|
||||
});
|
||||
}
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
actor,
|
||||
actorId,
|
||||
projectId: folder.projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Read,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment: folder.environment.envSlug,
|
||||
secretPath: folderWithPath.path,
|
||||
secretName: secret.key,
|
||||
secretTags: secret.tags.map((i) => i.slug)
|
||||
})
|
||||
);
|
||||
|
||||
if (secret.type === SecretType.Personal && secret.userId !== actorId) {
|
||||
throw new ForbiddenRequestError({
|
||||
message: "You are not allowed to access this secret",
|
||||
name: "GetSecretById"
|
||||
});
|
||||
}
|
||||
|
||||
const { decryptor: secretManagerDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||
type: KmsDataKey.SecretManager,
|
||||
projectId: folder.projectId
|
||||
});
|
||||
|
||||
const secretValue = secret.encryptedValue
|
||||
? secretManagerDecryptor({ cipherTextBlob: secret.encryptedValue }).toString()
|
||||
: "";
|
||||
|
||||
const secretComment = secret.encryptedComment
|
||||
? secretManagerDecryptor({ cipherTextBlob: secret.encryptedComment }).toString()
|
||||
: "";
|
||||
|
||||
return reshapeBridgeSecret(folder.projectId, folder.environment.envSlug, folderWithPath.path, {
|
||||
...secret,
|
||||
value: secretValue,
|
||||
comment: secretComment
|
||||
});
|
||||
};
|
||||
|
||||
const getSecretByName = async ({
|
||||
actorId,
|
||||
actor,
|
||||
@@ -2237,6 +2308,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
getSecretsCountMultiEnv,
|
||||
getSecretsMultiEnv,
|
||||
getSecretReferenceTree,
|
||||
getSecretsByFolderMappings
|
||||
getSecretsByFolderMappings,
|
||||
getSecretById
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user