mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: added support for getting imported secrets in v3 getSecret api
This commit is contained in:
@@ -146,7 +146,7 @@ export const getSecretsRaw = async (req: Request, res: Response) => {
|
||||
*/
|
||||
export const getSecretByNameRaw = async (req: Request, res: Response) => {
|
||||
const {
|
||||
query: { secretPath, environment, workspaceId, type },
|
||||
query: { secretPath, environment, workspaceId, type, include_imports },
|
||||
params: { secretName }
|
||||
} = await validateRequest(reqValidator.GetSecretByNameRawV3, req);
|
||||
|
||||
@@ -172,7 +172,8 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
|
||||
environment,
|
||||
type,
|
||||
secretPath,
|
||||
authData: req.authData
|
||||
authData: req.authData,
|
||||
include_imports
|
||||
});
|
||||
|
||||
const key = await BotService.getWorkspaceKeyWithBot({
|
||||
@@ -483,7 +484,7 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
*/
|
||||
export const getSecretByName = async (req: Request, res: Response) => {
|
||||
const {
|
||||
query: { secretPath, environment, workspaceId, type },
|
||||
query: { secretPath, environment, workspaceId, type, include_imports },
|
||||
params: { secretName }
|
||||
} = await validateRequest(reqValidator.GetSecretByNameV3, req);
|
||||
|
||||
@@ -509,7 +510,8 @@ export const getSecretByName = async (req: Request, res: Response) => {
|
||||
environment,
|
||||
type,
|
||||
secretPath,
|
||||
authData: req.authData
|
||||
authData: req.authData,
|
||||
include_imports
|
||||
});
|
||||
|
||||
return res.status(200).send({
|
||||
|
||||
@@ -48,6 +48,7 @@ import { getAuthDataPayloadIdObj, getAuthDataPayloadUserObj } from "../utils/aut
|
||||
import { getFolderByPath, getFolderIdFromServiceToken } from "../services/FolderService";
|
||||
import picomatch from "picomatch";
|
||||
import path from "path";
|
||||
import { getAnImportedSecret } from "../services/SecretImportService";
|
||||
|
||||
export const isValidScope = (
|
||||
authPayload: IServiceTokenData,
|
||||
@@ -622,13 +623,14 @@ export const getSecretHelper = async ({
|
||||
environment,
|
||||
type,
|
||||
authData,
|
||||
secretPath = "/"
|
||||
secretPath = "/",
|
||||
include_imports = true
|
||||
}: GetSecretParams) => {
|
||||
const secretBlindIndex = await generateSecretBlindIndexHelper({
|
||||
secretName,
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
let secret: ISecret | null = null;
|
||||
let secret: ISecret | null | undefined = null;
|
||||
// if using service token filter towards the folderId by secretpath
|
||||
|
||||
const folderId = await getFolderIdFromServiceToken(workspaceId, environment, secretPath);
|
||||
@@ -655,6 +657,11 @@ export const getSecretHelper = async ({
|
||||
}).lean();
|
||||
}
|
||||
|
||||
if (!secret && include_imports) {
|
||||
// if still no secret found search in imported secret and retreive
|
||||
secret = await getAnImportedSecret(secretName, workspaceId.toString(), environment, folderId);
|
||||
}
|
||||
|
||||
if (!secret) throw SecretNotFoundError();
|
||||
|
||||
// (EE) create (audit) log
|
||||
|
||||
@@ -19,7 +19,7 @@ export interface CreateSecretParams {
|
||||
secretPath: string;
|
||||
metadata?: {
|
||||
source?: string;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export interface GetSecretsParams {
|
||||
@@ -37,6 +37,7 @@ export interface GetSecretParams {
|
||||
environment: string;
|
||||
type?: "shared" | "personal";
|
||||
authData: AuthData;
|
||||
include_imports?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateSecretParams {
|
||||
|
||||
@@ -1,9 +1,61 @@
|
||||
import { Types } from "mongoose";
|
||||
import { generateSecretBlindIndexHelper } from "../helpers";
|
||||
import { Folder, ISecret, Secret, SecretImport } from "../models";
|
||||
import { getFolderByPath } from "./FolderService";
|
||||
|
||||
type TSecretImportFid = { environment: string; folderId: string; secretPath: string };
|
||||
|
||||
export const getAnImportedSecret = async (
|
||||
secretName: string,
|
||||
workspaceId: string,
|
||||
environment: string,
|
||||
folderId = "root"
|
||||
) => {
|
||||
const secretBlindIndex = await generateSecretBlindIndexHelper({
|
||||
secretName,
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
const secImports = await SecretImport.findOne({
|
||||
workspace: workspaceId,
|
||||
environment,
|
||||
folderId
|
||||
});
|
||||
if (!secImports) return;
|
||||
if (secImports.imports.length === 0) return;
|
||||
const folders = await Folder.find({
|
||||
workspace: workspaceId,
|
||||
environment: { $in: secImports.imports.map((el) => el.environment) }
|
||||
});
|
||||
|
||||
const importedSecByFid: TSecretImportFid[] = [];
|
||||
secImports.imports.forEach((el) => {
|
||||
const folder = folders.find((fl) => fl.environment === el.environment);
|
||||
if (folder) {
|
||||
const secPathFolder = getFolderByPath(folder.nodes, el.secretPath);
|
||||
if (secPathFolder)
|
||||
importedSecByFid.push({
|
||||
environment: el.environment,
|
||||
folderId: secPathFolder.id,
|
||||
secretPath: el.secretPath
|
||||
});
|
||||
} else {
|
||||
if (el.secretPath === "/") {
|
||||
// this happens when importing with a fresh env without any folders
|
||||
importedSecByFid.push({ environment: el.environment, folderId: "root", secretPath: "/" });
|
||||
}
|
||||
}
|
||||
});
|
||||
if (importedSecByFid.length === 0) return;
|
||||
|
||||
const secret = await Secret.findOne({
|
||||
workspace: workspaceId,
|
||||
secretBlindIndex
|
||||
}).or(importedSecByFid.map(({ environment, folderId }) => ({ environment, folder: folderId })));
|
||||
|
||||
return secret;
|
||||
};
|
||||
|
||||
export const getAllImportedSecrets = async (
|
||||
workspaceId: string,
|
||||
environment: string,
|
||||
|
||||
@@ -244,7 +244,11 @@ export const GetSecretByNameRawV3 = z.object({
|
||||
workspaceId: z.string().trim(),
|
||||
environment: z.string().trim(),
|
||||
secretPath: z.string().trim().default("/"),
|
||||
type: z.enum([SECRET_SHARED, SECRET_PERSONAL]).optional()
|
||||
type: z.enum([SECRET_SHARED, SECRET_PERSONAL]).optional(),
|
||||
include_imports: z
|
||||
.enum(["true", "false"])
|
||||
.default("true")
|
||||
.transform((value) => value === "true")
|
||||
})
|
||||
});
|
||||
|
||||
@@ -305,7 +309,11 @@ export const GetSecretByNameV3 = z.object({
|
||||
workspaceId: z.string().trim(),
|
||||
environment: z.string().trim(),
|
||||
secretPath: z.string().trim().default("/"),
|
||||
type: z.enum([SECRET_SHARED, SECRET_PERSONAL]).optional()
|
||||
type: z.enum([SECRET_SHARED, SECRET_PERSONAL]).optional(),
|
||||
include_imports: z
|
||||
.enum(["true", "false"])
|
||||
.default("true")
|
||||
.transform((value) => value === "true")
|
||||
}),
|
||||
params: z.object({
|
||||
secretName: z.string().trim()
|
||||
|
||||
Reference in New Issue
Block a user