feat(server): updated dynamic secret names from feedback, added describe and fixed login not working

This commit is contained in:
Akhil Mohan
2024-03-26 13:18:31 +05:30
parent b592f4cb6d
commit a7d2ec80c6
11 changed files with 259 additions and 139 deletions
@@ -32,7 +32,7 @@ export const dynamicSecretLeaseDALFactory = (db: TDbClient) => {
.select(selectAllTableCols(TableName.DynamicSecretLease))
.select(
db.ref("id").withSchema(TableName.DynamicSecret).as("dynId"),
db.ref("slug").withSchema(TableName.DynamicSecret).as("dynSlug"),
db.ref("name").withSchema(TableName.DynamicSecret).as("dynName"),
db.ref("version").withSchema(TableName.DynamicSecret).as("dynVersion"),
db.ref("type").withSchema(TableName.DynamicSecret).as("dynType"),
db.ref("defaultTTL").withSchema(TableName.DynamicSecret).as("dynDefaultTTL"),
@@ -54,7 +54,7 @@ export const dynamicSecretLeaseDALFactory = (db: TDbClient) => {
...DynamicSecretLeasesSchema.parse(doc),
dynamicSecret: {
id: doc.dynId,
slug: doc.dynSlug,
name: doc.dynName,
version: doc.dynVersion,
type: doc.dynType,
defaultTTL: doc.dynDefaultTTL,
@@ -45,9 +45,9 @@ export const dynamicSecretLeaseServiceFactory = ({
projectDAL
}: TDynamicSecretLeaseServiceFactoryDep) => {
const create = async ({
environment,
environmentSlug,
path,
slug,
name,
projectSlug,
actor,
actorId,
@@ -69,13 +69,13 @@ export const dynamicSecretLeaseServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ slug, folderId: folder.id });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" });
const totalLeasesTaken = await dynamicSecretLeaseDAL.countLeasesForDynamicSecret(dynamicSecretCfg.id);
@@ -119,7 +119,7 @@ export const dynamicSecretLeaseServiceFactory = ({
actor,
projectSlug,
path,
environment,
environmentSlug,
leaseId
}: TRenewDynamicSecretLeaseDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
@@ -135,10 +135,10 @@ export const dynamicSecretLeaseServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
@@ -180,7 +180,7 @@ export const dynamicSecretLeaseServiceFactory = ({
const revokeLease = async ({
leaseId,
environment,
environmentSlug,
path,
projectSlug,
actor,
@@ -202,10 +202,10 @@ export const dynamicSecretLeaseServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
@@ -245,12 +245,12 @@ export const dynamicSecretLeaseServiceFactory = ({
const listLeases = async ({
path,
slug,
name,
actor,
actorId,
projectSlug,
actorOrgId,
environment,
environmentSlug,
actorAuthMethod
}: TListDynamicSecretLeasesDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
@@ -266,13 +266,13 @@ export const dynamicSecretLeaseServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ slug, folderId: folder.id });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" });
const dynamicSecretLeases = await dynamicSecretLeaseDAL.find({ dynamicSecretId: dynamicSecretCfg.id });
@@ -283,7 +283,7 @@ export const dynamicSecretLeaseServiceFactory = ({
projectSlug,
actorOrgId,
path,
environment,
environmentSlug,
actor,
actorId,
leaseId,
@@ -302,10 +302,10 @@ export const dynamicSecretLeaseServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
@@ -5,9 +5,9 @@ export enum DynamicSecretLeaseStatus {
}
export type TCreateDynamicSecretLeaseDTO = {
slug: string;
name: string;
path: string;
environment: string;
environmentSlug: string;
ttl?: string;
projectSlug: string;
} & Omit<TProjectPermission, "projectId">;
@@ -15,21 +15,21 @@ export type TCreateDynamicSecretLeaseDTO = {
export type TDetailsDynamicSecretLeaseDTO = {
leaseId: string;
path: string;
environment: string;
environmentSlug: string;
projectSlug: string;
} & Omit<TProjectPermission, "projectId">;
export type TListDynamicSecretLeasesDTO = {
slug: string;
name: string;
path: string;
environment: string;
environmentSlug: string;
projectSlug: string;
} & Omit<TProjectPermission, "projectId">;
export type TDeleteDynamicSecretLeaseDTO = {
leaseId: string;
path: string;
environment: string;
environmentSlug: string;
projectSlug: string;
isForced?: boolean;
} & Omit<TProjectPermission, "projectId">;
@@ -37,7 +37,7 @@ export type TDeleteDynamicSecretLeaseDTO = {
export type TRenewDynamicSecretLeaseDTO = {
leaseId: string;
path: string;
environment: string;
environmentSlug: string;
ttl?: string;
projectSlug: string;
} & Omit<TProjectPermission, "projectId">;
@@ -48,11 +48,11 @@ export const dynamicSecretServiceFactory = ({
const create = async ({
path,
actor,
slug,
name,
actorId,
maxTTL,
provider,
environment,
environmentSlug,
projectSlug,
actorOrgId,
defaultTTL,
@@ -71,13 +71,13 @@ export const dynamicSecretServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const existingDynamicSecret = await dynamicSecretDAL.findOne({ slug, folderId: folder.id });
const existingDynamicSecret = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (existingDynamicSecret)
throw new BadRequestError({ message: "Provided dynamic secret already exist under the folder" });
@@ -99,22 +99,22 @@ export const dynamicSecretServiceFactory = ({
maxTTL,
defaultTTL,
folderId: folder.id,
slug
name
});
return dynamicSecretCfg;
};
const updateBySlug = async ({
slug,
const updateByName = async ({
name,
maxTTL,
defaultTTL,
inputs,
environment,
environmentSlug,
projectSlug,
path,
actor,
actorId,
newSlug,
newName,
actorOrgId,
actorAuthMethod
}: TUpdateDynamicSecretDTO) => {
@@ -132,17 +132,17 @@ export const dynamicSecretServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ slug, folderId: folder.id });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" });
if (newSlug) {
const existingDynamicSecret = await dynamicSecretDAL.findOne({ slug: newSlug, folderId: folder.id });
if (newName) {
const existingDynamicSecret = await dynamicSecretDAL.findOne({ name: newName, folderId: folder.id });
if (existingDynamicSecret)
throw new BadRequestError({ message: "Provided dynamic secret already exist under the folder" });
}
@@ -171,7 +171,7 @@ export const dynamicSecretServiceFactory = ({
keyEncoding: encryptedInput.encoding,
maxTTL,
defaultTTL,
slug: newSlug ?? slug,
name: newName ?? name,
status: null,
statusDetails: null
});
@@ -179,15 +179,15 @@ export const dynamicSecretServiceFactory = ({
return updatedDynamicCfg;
};
const deleteBySlug = async ({
const deleteByName = async ({
actorAuthMethod,
actorOrgId,
actorId,
actor,
projectSlug,
slug,
name,
path,
environment,
environmentSlug,
isForced
}: TDeleteDynamicSecretDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
@@ -204,13 +204,13 @@ export const dynamicSecretServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ slug, folderId: folder.id });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" });
const leases = await dynamicSecretLeaseDAL.find({ dynamicSecretId: dynamicSecretCfg.id });
@@ -239,10 +239,10 @@ export const dynamicSecretServiceFactory = ({
};
const getDetails = async ({
slug,
name,
projectSlug,
path,
environment,
environmentSlug,
actorAuthMethod,
actorOrgId,
actorId,
@@ -261,13 +261,13 @@ export const dynamicSecretServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ slug, folderId: folder.id });
const dynamicSecretCfg = await dynamicSecretDAL.findOne({ name, folderId: folder.id });
if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" });
const decryptedStoredInput = JSON.parse(
infisicalSymmetricDecrypt({
@@ -289,7 +289,7 @@ export const dynamicSecretServiceFactory = ({
actor,
projectSlug,
path,
environment
environmentSlug
}: TListDynamicSecretsDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new BadRequestError({ message: "Project not found" });
@@ -304,10 +304,10 @@ export const dynamicSecretServiceFactory = ({
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
subject(ProjectPermissionSub.Secrets, { environment: environmentSlug, secretPath: path })
);
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
const folder = await folderDAL.findBySecretPath(projectId, environmentSlug, path);
if (!folder) throw new BadRequestError({ message: "Folder not found" });
const dynamicSecretCfg = await dynamicSecretDAL.find({ folderId: folder.id });
@@ -316,8 +316,8 @@ export const dynamicSecretServiceFactory = ({
return {
create,
updateBySlug,
deleteBySlug,
updateByName,
deleteByName,
getDetails,
list
};
@@ -16,39 +16,39 @@ export type TCreateDynamicSecretDTO = {
defaultTTL: string;
maxTTL?: string | null;
path: string;
environment: string;
slug: string;
environmentSlug: string;
name: string;
projectSlug: string;
} & Omit<TProjectPermission, "projectId">;
export type TUpdateDynamicSecretDTO = {
slug: string;
newSlug?: string;
name: string;
newName?: string;
defaultTTL?: string;
maxTTL?: string | null;
path: string;
environment: string;
environmentSlug: string;
inputs?: TProvider["inputs"];
projectSlug: string;
} & Omit<TProjectPermission, "projectId">;
export type TDeleteDynamicSecretDTO = {
slug: string;
name: string;
path: string;
environment: string;
environmentSlug: string;
projectSlug: string;
isForced?: boolean;
} & Omit<TProjectPermission, "projectId">;
export type TDetailsDynamicSecretDTO = {
slug: string;
name: string;
path: string;
environment: string;
environmentSlug: string;
projectSlug: string;
} & Omit<TProjectPermission, "projectId">;
export type TListDynamicSecretsDTO = {
path: string;
environment: string;
environmentSlug: string;
projectSlug: string;
} & Omit<TProjectPermission, "projectId">;
@@ -13,8 +13,8 @@ import { DynamicSecretSqlDBSchema, TDynamicProviderFns } from "./models";
const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000;
const generatePassword = (size?: number) => {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*'$#";
return customAlphabet(charset, 32)(size);
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*$#";
return customAlphabet(charset, 48)(size);
};
export const SqlDatabaseProvider = (): TDynamicProviderFns => {
@@ -61,13 +61,13 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => {
const providerInputs = await validateProviderInputs(inputs);
const db = await getClient(providerInputs);
const username = alphaNumericNanoId(21);
const username = alphaNumericNanoId(32);
const password = generatePassword();
const expiration = new Date(expireAt).toISOString();
const creationStatement = handlebars.compile(providerInputs.creationStatement, { noEscape: true })({
username,
password: "infisical",
password,
expiration
});