mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 06:28:11 +00:00
feat: changed the whole api from projectid to slug
This commit is contained in:
Vendored
+1
-1
@@ -64,7 +64,7 @@ declare module "fastify" {
|
|||||||
authMethod: ActorAuthMethod;
|
authMethod: ActorAuthMethod;
|
||||||
type: ActorType;
|
type: ActorType;
|
||||||
id: string;
|
id: string;
|
||||||
orgId?: string;
|
orgId: string;
|
||||||
};
|
};
|
||||||
// passport data
|
// passport data
|
||||||
passportUser: {
|
passportUser: {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export type TProjectPermission = {
|
|||||||
actorId: string;
|
actorId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
actorAuthMethod: ActorAuthMethod;
|
actorAuthMethod: ActorAuthMethod;
|
||||||
actorOrgId: string | undefined;
|
actorOrgId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RequiredKeys<T> = {
|
export type RequiredKeys<T> = {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export type TAuthMode =
|
|||||||
userId: string;
|
userId: string;
|
||||||
tokenVersionId: string; // the session id of token used
|
tokenVersionId: string; // the session id of token used
|
||||||
user: TUsers;
|
user: TUsers;
|
||||||
orgId?: string;
|
orgId: string;
|
||||||
authMethod: AuthMethod;
|
authMethod: AuthMethod;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
@@ -119,7 +119,7 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
|
|||||||
userId: user.id,
|
userId: user.id,
|
||||||
tokenVersionId,
|
tokenVersionId,
|
||||||
actor,
|
actor,
|
||||||
orgId,
|
orgId: orgId as string,
|
||||||
authMethod: token.authMethod
|
authMethod: token.authMethod
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -566,6 +566,7 @@ export const registerRoutes = async (
|
|||||||
dynamicSecretDAL
|
dynamicSecretDAL
|
||||||
});
|
});
|
||||||
const dynamicSecretService = dynamicSecretServiceFactory({
|
const dynamicSecretService = dynamicSecretServiceFactory({
|
||||||
|
projectDAL,
|
||||||
dynamicSecretQueueService,
|
dynamicSecretQueueService,
|
||||||
dynamicSecretDAL,
|
dynamicSecretDAL,
|
||||||
dynamicSecretLeaseDAL,
|
dynamicSecretLeaseDAL,
|
||||||
@@ -574,6 +575,7 @@ export const registerRoutes = async (
|
|||||||
permissionService
|
permissionService
|
||||||
});
|
});
|
||||||
const dynamicSecretLeaseService = dynamicSecretLeaseServiceFactory({
|
const dynamicSecretLeaseService = dynamicSecretLeaseServiceFactory({
|
||||||
|
projectDAL,
|
||||||
permissionService,
|
permissionService,
|
||||||
dynamicSecretQueueService,
|
dynamicSecretQueueService,
|
||||||
dynamicSecretDAL,
|
dynamicSecretDAL,
|
||||||
|
|||||||
@@ -7,14 +7,16 @@ import { removeTrailingSlash } from "@app/lib/fn";
|
|||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
import { AuthMode } from "@app/services/auth/auth-type";
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
|
import { SanitizedDynamicSecretSchema } from "../sanitizedSchemas";
|
||||||
|
|
||||||
export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvider) => {
|
export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvider) => {
|
||||||
server.route({
|
server.route({
|
||||||
url: "/",
|
url: "/",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
schema: {
|
schema: {
|
||||||
body: z.object({
|
body: z.object({
|
||||||
slug: z.string(),
|
slug: z.string().min(1),
|
||||||
projectId: z.string(),
|
projectSlug: z.string().min(1),
|
||||||
ttl: z
|
ttl: z
|
||||||
.string()
|
.string()
|
||||||
.optional()
|
.optional()
|
||||||
@@ -27,7 +29,7 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide
|
|||||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
|
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
|
||||||
}),
|
}),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
environment: z.string()
|
environment: z.string().min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -57,9 +59,9 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide
|
|||||||
leaseId: z.string()
|
leaseId: z.string()
|
||||||
}),
|
}),
|
||||||
body: z.object({
|
body: z.object({
|
||||||
projectId: z.string(),
|
projectSlug: z.string().min(1),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
path: z.string().min(1).trim().default("/").transform(removeTrailingSlash),
|
||||||
environment: z.string()
|
environment: z.string().min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -100,9 +102,9 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide
|
|||||||
if (valMs > daysToMillisecond(1))
|
if (valMs > daysToMillisecond(1))
|
||||||
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
|
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "TTL must be less than a day" });
|
||||||
}),
|
}),
|
||||||
projectId: z.string(),
|
projectSlug: z.string().min(1),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
path: z.string().min(1).trim().default("/").transform(removeTrailingSlash),
|
||||||
environment: z.string()
|
environment: z.string().min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -125,34 +127,36 @@ export const registerDynamicSecretLeaseRouter = async (server: FastifyZodProvide
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
url: "/:slug",
|
url: "/:leaseId",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
schema: {
|
schema: {
|
||||||
params: z.object({
|
params: z.object({
|
||||||
slug: z.string()
|
leaseId: z.string()
|
||||||
}),
|
}),
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
projectId: z.string(),
|
projectSlug: z.string().min(1),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
environment: z.string()
|
environment: z.string().min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
leases: DynamicSecretLeasesSchema.array()
|
lease: DynamicSecretLeasesSchema.extend({
|
||||||
|
dynamicSecret: SanitizedDynamicSecretSchema
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const leases = await server.services.dynamicSecretLease.listLeases({
|
const lease = await server.services.dynamicSecretLease.getLeaseDetails({
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actorAuthMethod: req.permission.authMethod,
|
actorAuthMethod: req.permission.authMethod,
|
||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
slug: req.params.slug,
|
leaseId: req.params.leaseId,
|
||||||
...req.query
|
...req.query
|
||||||
});
|
});
|
||||||
return { leases };
|
return { lease };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import ms from "ms";
|
import ms from "ms";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { DynamicSecretLeasesSchema } from "@app/db/schemas";
|
||||||
import { daysToMillisecond } from "@app/lib/dates";
|
import { daysToMillisecond } from "@app/lib/dates";
|
||||||
import { removeTrailingSlash } from "@app/lib/fn";
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
@@ -15,7 +16,7 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
|
|||||||
method: "POST",
|
method: "POST",
|
||||||
schema: {
|
schema: {
|
||||||
body: z.object({
|
body: z.object({
|
||||||
projectId: z.string(),
|
projectSlug: z.string().min(1),
|
||||||
provider: DynamicSecretProviderSchema,
|
provider: DynamicSecretProviderSchema,
|
||||||
defaultTTL: z.string().superRefine((val, ctx) => {
|
defaultTTL: z.string().superRefine((val, ctx) => {
|
||||||
const valMs = ms(val);
|
const valMs = ms(val);
|
||||||
@@ -37,8 +38,8 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
|
|||||||
})
|
})
|
||||||
.nullable(),
|
.nullable(),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
environment: z.string(),
|
environment: z.string().min(1),
|
||||||
slug: z.string().toLowerCase()
|
slug: z.string().min(1).toLowerCase()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -67,9 +68,9 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
|
|||||||
slug: z.string()
|
slug: z.string()
|
||||||
}),
|
}),
|
||||||
body: z.object({
|
body: z.object({
|
||||||
projectId: z.string(),
|
projectSlug: z.string().min(1),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
environment: z.string(),
|
environment: z.string().min(1),
|
||||||
data: z.object({
|
data: z.object({
|
||||||
inputs: z.any().optional(),
|
inputs: z.any().optional(),
|
||||||
defaultTTL: z
|
defaultTTL: z
|
||||||
@@ -113,7 +114,7 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
|
|||||||
actorOrgId: req.permission.orgId,
|
actorOrgId: req.permission.orgId,
|
||||||
slug: req.params.slug,
|
slug: req.params.slug,
|
||||||
path: req.body.path,
|
path: req.body.path,
|
||||||
projectId: req.body.projectId,
|
projectSlug: req.body.projectSlug,
|
||||||
environment: req.body.environment,
|
environment: req.body.environment,
|
||||||
...req.body.data
|
...req.body.data
|
||||||
});
|
});
|
||||||
@@ -129,9 +130,9 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
|
|||||||
slug: z.string()
|
slug: z.string()
|
||||||
}),
|
}),
|
||||||
body: z.object({
|
body: z.object({
|
||||||
projectId: z.string(),
|
projectSlug: z.string().min(1),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
environment: z.string()
|
environment: z.string().min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -161,9 +162,9 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
|
|||||||
slug: z.string()
|
slug: z.string()
|
||||||
}),
|
}),
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
projectId: z.string(),
|
projectSlug: z.string().min(1),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
environment: z.string()
|
environment: z.string().min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -192,9 +193,9 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
|
|||||||
method: "GET",
|
method: "GET",
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
projectId: z.string(),
|
projectSlug: z.string().min(1),
|
||||||
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
environment: z.string()
|
environment: z.string().min(1)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -214,4 +215,36 @@ export const registerDynamicSecretRouter = async (server: FastifyZodProvider) =>
|
|||||||
return { dynamicSecrets: dynamicSecretCfgs };
|
return { dynamicSecrets: dynamicSecretCfgs };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/:slug/leases",
|
||||||
|
method: "GET",
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
slug: z.string()
|
||||||
|
}),
|
||||||
|
querystring: z.object({
|
||||||
|
projectSlug: z.string().min(1),
|
||||||
|
path: z.string().trim().default("/").transform(removeTrailingSlash),
|
||||||
|
environment: z.string().min(1)
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
leases: DynamicSecretLeasesSchema.array()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const leases = await server.services.dynamicSecretLease.listLeases({
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actorAuthMethod: req.permission.authMethod,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
slug: req.params.slug,
|
||||||
|
...req.query
|
||||||
|
});
|
||||||
|
return { leases };
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,71 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
import { TDbClient } from "@app/db";
|
import { TDbClient } from "@app/db";
|
||||||
import { TableName } from "@app/db/schemas";
|
import { DynamicSecretLeasesSchema, TableName } from "@app/db/schemas";
|
||||||
import { ormify } from "@app/lib/knex";
|
import { DatabaseError } from "@app/lib/errors";
|
||||||
|
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
||||||
|
|
||||||
export type TDynamicSecretLeaseDALFactory = ReturnType<typeof dynamicSecretLeaseDALFactory>;
|
export type TDynamicSecretLeaseDALFactory = ReturnType<typeof dynamicSecretLeaseDALFactory>;
|
||||||
|
|
||||||
export const dynamicSecretLeaseDALFactory = (db: TDbClient) => {
|
export const dynamicSecretLeaseDALFactory = (db: TDbClient) => {
|
||||||
const orm = ormify(db, TableName.DynamicSecretLease);
|
const orm = ormify(db, TableName.DynamicSecretLease);
|
||||||
return orm;
|
|
||||||
|
const findById = async (id: string, tx?: Knex) => {
|
||||||
|
try {
|
||||||
|
const doc = await (tx || db)(TableName.DynamicSecretLease)
|
||||||
|
.where({ id })
|
||||||
|
.first()
|
||||||
|
.join(
|
||||||
|
TableName.DynamicSecret,
|
||||||
|
`${TableName.DynamicSecretLease}.dynamicSecretId`,
|
||||||
|
`${TableName.DynamicSecret}.id`
|
||||||
|
)
|
||||||
|
.select(selectAllTableCols(TableName.DynamicSecretLease))
|
||||||
|
.select(
|
||||||
|
db.ref("id").withSchema(TableName.DynamicSecret).as("dynId"),
|
||||||
|
db.ref("slug").withSchema(TableName.DynamicSecret).as("dynSlug"),
|
||||||
|
db.ref("version").withSchema(TableName.DynamicSecret).as("dynVersion"),
|
||||||
|
db.ref("type").withSchema(TableName.DynamicSecret).as("dynType"),
|
||||||
|
db.ref("defaultTTL").withSchema(TableName.DynamicSecret).as("dynDefaultTTL"),
|
||||||
|
db.ref("maxTTL").withSchema(TableName.DynamicSecret).as("dynMaxTTL"),
|
||||||
|
db.ref("inputIV").withSchema(TableName.DynamicSecret).as("dynInputIV"),
|
||||||
|
db.ref("inputTag").withSchema(TableName.DynamicSecret).as("dynInputTag"),
|
||||||
|
db.ref("inputCiphertext").withSchema(TableName.DynamicSecret).as("dynInputCiphertext"),
|
||||||
|
db.ref("algorithm").withSchema(TableName.DynamicSecret).as("dynAlgorithm"),
|
||||||
|
db.ref("keyEncoding").withSchema(TableName.DynamicSecret).as("dynKeyEncoding"),
|
||||||
|
db.ref("folderId").withSchema(TableName.DynamicSecret).as("dynFolderId"),
|
||||||
|
db.ref("status").withSchema(TableName.DynamicSecret).as("dynStatus"),
|
||||||
|
db.ref("statusDetails").withSchema(TableName.DynamicSecret).as("dynStatusDetails"),
|
||||||
|
db.ref("createdAt").withSchema(TableName.DynamicSecret).as("dynCreatedAt"),
|
||||||
|
db.ref("updatedAt").withSchema(TableName.DynamicSecret).as("dynUpdatedAt")
|
||||||
|
);
|
||||||
|
if (!doc) return;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...DynamicSecretLeasesSchema.parse(doc),
|
||||||
|
dynamicSecret: {
|
||||||
|
id: doc.dynId,
|
||||||
|
slug: doc.dynSlug,
|
||||||
|
version: doc.dynVersion,
|
||||||
|
type: doc.dynType,
|
||||||
|
defaultTTL: doc.dynDefaultTTL,
|
||||||
|
maxTTL: doc.dynMaxTTL,
|
||||||
|
inputIV: doc.dynInputIV,
|
||||||
|
inputTag: doc.dynInputTag,
|
||||||
|
inputCiphertext: doc.dynInputCiphertext,
|
||||||
|
algorithm: doc.dynAlgorithm,
|
||||||
|
keyEncoding: doc.dynKeyEncoding,
|
||||||
|
folderId: doc.dynFolderId,
|
||||||
|
status: doc.dynStatus,
|
||||||
|
statusDetails: doc.dynStatusDetails,
|
||||||
|
createdAt: doc.dynCreatedAt,
|
||||||
|
updatedAt: doc.dynUpdatedAt
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
throw new DatabaseError({ error, name: "DynamicSecretLeaseFindById" });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return { ...orm, findById };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ import { BadRequestError } from "@app/lib/errors";
|
|||||||
|
|
||||||
import { TDynamicSecretDALFactory } from "../dynamic-secret/dynamic-secret-dal";
|
import { TDynamicSecretDALFactory } from "../dynamic-secret/dynamic-secret-dal";
|
||||||
import { DynamicSecretProviders, TDynamicProviderFns } from "../dynamic-secret/providers/models";
|
import { DynamicSecretProviders, TDynamicProviderFns } from "../dynamic-secret/providers/models";
|
||||||
|
import { TProjectDALFactory } from "../project/project-dal";
|
||||||
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
|
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
|
||||||
import { TDynamicSecretLeaseDALFactory } from "./dynamic-secret-lease-dal";
|
import { TDynamicSecretLeaseDALFactory } from "./dynamic-secret-lease-dal";
|
||||||
import { TDynamicSecretLeaseQueueServiceFactory } from "./dynamic-secret-lease-queue";
|
import { TDynamicSecretLeaseQueueServiceFactory } from "./dynamic-secret-lease-queue";
|
||||||
import {
|
import {
|
||||||
TCreateDynamicSecretLeaseDTO,
|
TCreateDynamicSecretLeaseDTO,
|
||||||
TDeleteDynamicSecretLeaseDTO,
|
TDeleteDynamicSecretLeaseDTO,
|
||||||
|
TDetailsDynamicSecretLeaseDTO,
|
||||||
TListDynamicSecretLeasesDTO,
|
TListDynamicSecretLeasesDTO,
|
||||||
TRenewDynamicSecretLeaseDTO
|
TRenewDynamicSecretLeaseDTO
|
||||||
} from "./dynamic-secret-lease-types";
|
} from "./dynamic-secret-lease-types";
|
||||||
@@ -26,6 +28,7 @@ type TDynamicSecretLeaseServiceFactoryDep = {
|
|||||||
dynamicSecretQueueService: TDynamicSecretLeaseQueueServiceFactory;
|
dynamicSecretQueueService: TDynamicSecretLeaseQueueServiceFactory;
|
||||||
folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath">;
|
folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
|
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDynamicSecretLeaseServiceFactory = ReturnType<typeof dynamicSecretLeaseServiceFactory>;
|
export type TDynamicSecretLeaseServiceFactory = ReturnType<typeof dynamicSecretLeaseServiceFactory>;
|
||||||
@@ -36,19 +39,24 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
dynamicSecretDAL,
|
dynamicSecretDAL,
|
||||||
folderDAL,
|
folderDAL,
|
||||||
permissionService,
|
permissionService,
|
||||||
dynamicSecretQueueService
|
dynamicSecretQueueService,
|
||||||
|
projectDAL
|
||||||
}: TDynamicSecretLeaseServiceFactoryDep) => {
|
}: TDynamicSecretLeaseServiceFactoryDep) => {
|
||||||
const create = async ({
|
const create = async ({
|
||||||
environment,
|
environment,
|
||||||
path,
|
path,
|
||||||
slug,
|
slug,
|
||||||
projectId,
|
projectSlug,
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
ttl
|
ttl
|
||||||
}: TCreateDynamicSecretLeaseDTO) => {
|
}: TCreateDynamicSecretLeaseDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -57,7 +65,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
actorOrgId
|
actorOrgId
|
||||||
);
|
);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Edit,
|
ProjectPermissionActions.Create,
|
||||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
|
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -102,11 +110,15 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
actorOrgId,
|
actorOrgId,
|
||||||
actorId,
|
actorId,
|
||||||
actor,
|
actor,
|
||||||
projectId,
|
projectSlug,
|
||||||
path,
|
path,
|
||||||
environment,
|
environment,
|
||||||
leaseId
|
leaseId
|
||||||
}: TRenewDynamicSecretLeaseDTO) => {
|
}: TRenewDynamicSecretLeaseDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -125,12 +137,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
|
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
|
||||||
if (!dynamicSecretLease) throw new BadRequestError({ message: "Dynamic secret lease not found" });
|
if (!dynamicSecretLease) throw new BadRequestError({ message: "Dynamic secret lease not found" });
|
||||||
|
|
||||||
const dynamicSecretCfg = await dynamicSecretDAL.findOne({
|
const dynamicSecretCfg = dynamicSecretLease.dynamicSecret;
|
||||||
id: dynamicSecretLease.dynamicSecretId,
|
|
||||||
folderId: folder.id
|
|
||||||
});
|
|
||||||
if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" });
|
|
||||||
|
|
||||||
const selectedProvider = dynamicSecretProviders[dynamicSecretCfg.type as DynamicSecretProviders];
|
const selectedProvider = dynamicSecretProviders[dynamicSecretCfg.type as DynamicSecretProviders];
|
||||||
const decryptedStoredInput = JSON.parse(
|
const decryptedStoredInput = JSON.parse(
|
||||||
infisicalSymmetricDecrypt({
|
infisicalSymmetricDecrypt({
|
||||||
@@ -168,12 +175,16 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
leaseId,
|
leaseId,
|
||||||
environment,
|
environment,
|
||||||
path,
|
path,
|
||||||
projectId,
|
projectSlug,
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
actorAuthMethod
|
actorAuthMethod
|
||||||
}: TDeleteDynamicSecretLeaseDTO) => {
|
}: TDeleteDynamicSecretLeaseDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -182,7 +193,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
actorOrgId
|
actorOrgId
|
||||||
);
|
);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Edit,
|
ProjectPermissionActions.Delete,
|
||||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
|
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -192,12 +203,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
|
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
|
||||||
if (!dynamicSecretLease) throw new BadRequestError({ message: "Dynamic secret lease not found" });
|
if (!dynamicSecretLease) throw new BadRequestError({ message: "Dynamic secret lease not found" });
|
||||||
|
|
||||||
const dynamicSecretCfg = await dynamicSecretDAL.findOne({
|
const dynamicSecretCfg = dynamicSecretLease.dynamicSecret;
|
||||||
id: dynamicSecretLease.dynamicSecretId,
|
|
||||||
folderId: folder.id
|
|
||||||
});
|
|
||||||
if (!dynamicSecretCfg) throw new BadRequestError({ message: "Dynamic secret not found" });
|
|
||||||
|
|
||||||
const selectedProvider = dynamicSecretProviders[dynamicSecretCfg.type as DynamicSecretProviders];
|
const selectedProvider = dynamicSecretProviders[dynamicSecretCfg.type as DynamicSecretProviders];
|
||||||
const decryptedStoredInput = JSON.parse(
|
const decryptedStoredInput = JSON.parse(
|
||||||
infisicalSymmetricDecrypt({
|
infisicalSymmetricDecrypt({
|
||||||
@@ -220,11 +226,15 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
slug,
|
slug,
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
projectId,
|
projectSlug,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
environment,
|
environment,
|
||||||
actorAuthMethod
|
actorAuthMethod
|
||||||
}: TListDynamicSecretLeasesDTO) => {
|
}: TListDynamicSecretLeasesDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -233,7 +243,7 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
actorOrgId
|
actorOrgId
|
||||||
);
|
);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionActions.Edit,
|
ProjectPermissionActions.Read,
|
||||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
|
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -247,10 +257,46 @@ export const dynamicSecretLeaseServiceFactory = ({
|
|||||||
return dynamicSecretLeases;
|
return dynamicSecretLeases;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getLeaseDetails = async ({
|
||||||
|
projectSlug,
|
||||||
|
actorOrgId,
|
||||||
|
path,
|
||||||
|
environment,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
leaseId,
|
||||||
|
actorAuthMethod
|
||||||
|
}: TDetailsDynamicSecretLeaseDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
projectId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
);
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
|
||||||
|
);
|
||||||
|
|
||||||
|
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
|
||||||
|
if (!folder) throw new BadRequestError({ message: "Folder not found" });
|
||||||
|
|
||||||
|
const dynamicSecretLease = await dynamicSecretLeaseDAL.findById(leaseId);
|
||||||
|
if (!dynamicSecretLease) throw new BadRequestError({ message: "Dynamic secret lease not found" });
|
||||||
|
|
||||||
|
return dynamicSecretLease;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
create,
|
create,
|
||||||
listLeases,
|
listLeases,
|
||||||
revokeLease,
|
revokeLease,
|
||||||
renewLease
|
renewLease,
|
||||||
|
getLeaseDetails
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,23 +9,34 @@ export type TCreateDynamicSecretLeaseDTO = {
|
|||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
ttl?: string;
|
ttl?: string;
|
||||||
} & TProjectPermission;
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
|
export type TDetailsDynamicSecretLeaseDTO = {
|
||||||
|
leaseId: string;
|
||||||
|
path: string;
|
||||||
|
environment: string;
|
||||||
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TListDynamicSecretLeasesDTO = {
|
export type TListDynamicSecretLeasesDTO = {
|
||||||
slug: string;
|
slug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
} & TProjectPermission;
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TDeleteDynamicSecretLeaseDTO = {
|
export type TDeleteDynamicSecretLeaseDTO = {
|
||||||
leaseId: string;
|
leaseId: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
} & TProjectPermission;
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TRenewDynamicSecretLeaseDTO = {
|
export type TRenewDynamicSecretLeaseDTO = {
|
||||||
leaseId: string;
|
leaseId: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
ttl?: string;
|
ttl?: string;
|
||||||
} & TProjectPermission;
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { BadRequestError } from "@app/lib/errors";
|
|||||||
|
|
||||||
import { TDynamicSecretLeaseDALFactory } from "../dynamic-secret-lease/dynamic-secret-lease-dal";
|
import { TDynamicSecretLeaseDALFactory } from "../dynamic-secret-lease/dynamic-secret-lease-dal";
|
||||||
import { TDynamicSecretLeaseQueueServiceFactory } from "../dynamic-secret-lease/dynamic-secret-lease-queue";
|
import { TDynamicSecretLeaseQueueServiceFactory } from "../dynamic-secret-lease/dynamic-secret-lease-queue";
|
||||||
|
import { TProjectDALFactory } from "../project/project-dal";
|
||||||
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
|
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
|
||||||
import { TDynamicSecretDALFactory } from "./dynamic-secret-dal";
|
import { TDynamicSecretDALFactory } from "./dynamic-secret-dal";
|
||||||
import {
|
import {
|
||||||
@@ -26,6 +27,7 @@ type TDynamicSecretServiceFactoryDep = {
|
|||||||
dynamicSecretProviders: Record<DynamicSecretProviders, TDynamicProviderFns>;
|
dynamicSecretProviders: Record<DynamicSecretProviders, TDynamicProviderFns>;
|
||||||
dynamicSecretQueueService: Pick<TDynamicSecretLeaseQueueServiceFactory, "pruneDynamicSecret">;
|
dynamicSecretQueueService: Pick<TDynamicSecretLeaseQueueServiceFactory, "pruneDynamicSecret">;
|
||||||
folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath">;
|
folderDAL: Pick<TSecretFolderDALFactory, "findBySecretPath">;
|
||||||
|
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,7 +39,8 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
folderDAL,
|
folderDAL,
|
||||||
dynamicSecretProviders,
|
dynamicSecretProviders,
|
||||||
permissionService,
|
permissionService,
|
||||||
dynamicSecretQueueService
|
dynamicSecretQueueService,
|
||||||
|
projectDAL
|
||||||
}: TDynamicSecretServiceFactoryDep) => {
|
}: TDynamicSecretServiceFactoryDep) => {
|
||||||
const create = async ({
|
const create = async ({
|
||||||
path,
|
path,
|
||||||
@@ -47,11 +50,15 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
maxTTL,
|
maxTTL,
|
||||||
provider,
|
provider,
|
||||||
environment,
|
environment,
|
||||||
projectId,
|
projectSlug,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
defaultTTL,
|
defaultTTL,
|
||||||
actorAuthMethod
|
actorAuthMethod
|
||||||
}: TCreateDynamicSecretDTO) => {
|
}: TCreateDynamicSecretDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -96,7 +103,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
defaultTTL,
|
defaultTTL,
|
||||||
inputs,
|
inputs,
|
||||||
environment,
|
environment,
|
||||||
projectId,
|
projectSlug,
|
||||||
path,
|
path,
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -104,6 +111,11 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorOrgId,
|
actorOrgId,
|
||||||
actorAuthMethod
|
actorAuthMethod
|
||||||
}: TUpdateDynamicSecretDTO) => {
|
}: TUpdateDynamicSecretDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -161,11 +173,16 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorOrgId,
|
actorOrgId,
|
||||||
actorId,
|
actorId,
|
||||||
actor,
|
actor,
|
||||||
projectId,
|
projectSlug,
|
||||||
slug,
|
slug,
|
||||||
path,
|
path,
|
||||||
environment
|
environment
|
||||||
}: TDeleteDynamicSecretDTO) => {
|
}: TDeleteDynamicSecretDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -201,7 +218,7 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
|
|
||||||
const getDetails = async ({
|
const getDetails = async ({
|
||||||
slug,
|
slug,
|
||||||
projectId,
|
projectSlug,
|
||||||
path,
|
path,
|
||||||
environment,
|
environment,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
@@ -209,6 +226,10 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorId,
|
actorId,
|
||||||
actor
|
actor
|
||||||
}: TDetailsDynamicSecretDTO) => {
|
}: TDetailsDynamicSecretDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -244,10 +265,14 @@ export const dynamicSecretServiceFactory = ({
|
|||||||
actorOrgId,
|
actorOrgId,
|
||||||
actorId,
|
actorId,
|
||||||
actor,
|
actor,
|
||||||
projectId,
|
projectSlug,
|
||||||
path,
|
path,
|
||||||
environment
|
environment
|
||||||
}: TListDynamicSecretsDTO) => {
|
}: TListDynamicSecretsDTO) => {
|
||||||
|
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
|
||||||
|
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||||
|
|
||||||
|
const projectId = project.id;
|
||||||
const { permission } = await permissionService.getProjectPermission(
|
const { permission } = await permissionService.getProjectPermission(
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ export type TCreateDynamicSecretDTO = {
|
|||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
} & TProjectPermission;
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TUpdateDynamicSecretDTO = {
|
export type TUpdateDynamicSecretDTO = {
|
||||||
slug: string;
|
slug: string;
|
||||||
@@ -28,21 +29,25 @@ export type TUpdateDynamicSecretDTO = {
|
|||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
inputs?: TProvider["inputs"];
|
inputs?: TProvider["inputs"];
|
||||||
} & TProjectPermission;
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TDeleteDynamicSecretDTO = {
|
export type TDeleteDynamicSecretDTO = {
|
||||||
slug: string;
|
slug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
} & TProjectPermission;
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TDetailsDynamicSecretDTO = {
|
export type TDetailsDynamicSecretDTO = {
|
||||||
slug: string;
|
slug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
} & TProjectPermission;
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|
||||||
export type TListDynamicSecretsDTO = {
|
export type TListDynamicSecretsDTO = {
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
} & TProjectPermission;
|
projectSlug: string;
|
||||||
|
} & Omit<TProjectPermission, "projectId">;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { DynamicSecretSqlDBSchema, TDynamicProviderFns } from "./models";
|
|||||||
const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000;
|
const EXTERNAL_REQUEST_TIMEOUT = 10 * 1000;
|
||||||
|
|
||||||
const generatePassword = (size?: number) => {
|
const generatePassword = (size?: number) => {
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%^&*()_+-=[]{}|;,./<>";
|
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!*'$#";
|
||||||
return customAlphabet(charset, 20)(size);
|
return customAlphabet(charset, 20)(size);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => {
|
|||||||
|
|
||||||
await db.raw(creationStatement.toString());
|
await db.raw(creationStatement.toString());
|
||||||
await db.destroy();
|
await db.destroy();
|
||||||
return { entityId: username, data: { username, password } };
|
return { entityId: username, data: { DB_USERNAME: username, DB_PASSWORD: password } };
|
||||||
};
|
};
|
||||||
|
|
||||||
const revoke = async (inputs: unknown, entityId: string) => {
|
const revoke = async (inputs: unknown, entityId: string) => {
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ export const useCreateDynamicSecret = () => {
|
|||||||
);
|
);
|
||||||
return data.dynamicSecret;
|
return data.dynamicSecret;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { path, environment, projectId }) => {
|
onSuccess: (_, { path, environment, projectSlug }) => {
|
||||||
queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectId, environment }));
|
queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectSlug, environment }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -38,8 +38,8 @@ export const useUpdateDynamicSecret = () => {
|
|||||||
);
|
);
|
||||||
return data.dynamicSecret;
|
return data.dynamicSecret;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { path, environment, projectId }) => {
|
onSuccess: (_, { path, environment, projectSlug }) => {
|
||||||
queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectId, environment }));
|
queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectSlug, environment }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -55,8 +55,8 @@ export const useDeleteDynamicSecret = () => {
|
|||||||
);
|
);
|
||||||
return data.dynamicSecret;
|
return data.dynamicSecret;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { path, environment, projectId }) => {
|
onSuccess: (_, { path, environment, projectSlug }) => {
|
||||||
queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectId, environment }));
|
queryClient.invalidateQueries(dynamicSecretKeys.list({ path, projectSlug, environment }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,25 +6,25 @@ import { TDetailsDynamicSecretDTO, TDynamicSecret, TListDynamicSecretDTO } from
|
|||||||
|
|
||||||
export const dynamicSecretKeys = {
|
export const dynamicSecretKeys = {
|
||||||
list: ({
|
list: ({
|
||||||
projectId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
path
|
path
|
||||||
}: Pick<TListDynamicSecretDTO, "path" | "environment" | "projectId">) =>
|
}: Pick<TListDynamicSecretDTO, "path" | "environment" | "projectSlug">) =>
|
||||||
[{ projectId, environment, path }, "dynamic-secrets"] as const,
|
[{ projectSlug, environment, path }, "dynamic-secrets"] as const,
|
||||||
details: ({ path, environment, projectId, slug }: TDetailsDynamicSecretDTO) =>
|
details: ({ path, environment, projectSlug, slug }: TDetailsDynamicSecretDTO) =>
|
||||||
[{ projectId, path, environment, slug }, "dynamic-secret-details"] as const
|
[{ projectSlug, path, environment, slug }, "dynamic-secret-details"] as const
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetDynamicSecrets = ({ projectId, environment, path }: TListDynamicSecretDTO) => {
|
export const useGetDynamicSecrets = ({ projectSlug, environment, path }: TListDynamicSecretDTO) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: dynamicSecretKeys.list({ path, environment, projectId }),
|
queryKey: dynamicSecretKeys.list({ path, environment, projectSlug }),
|
||||||
enabled: Boolean(projectId && environment && path),
|
enabled: Boolean(projectSlug && environment && path),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await apiRequest.get<{ dynamicSecrets: TDynamicSecret[] }>(
|
const { data } = await apiRequest.get<{ dynamicSecrets: TDynamicSecret[] }>(
|
||||||
"/api/v1/dynamic-secrets",
|
"/api/v1/dynamic-secrets",
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
projectId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
@@ -37,20 +37,20 @@ export const useGetDynamicSecrets = ({ projectId, environment, path }: TListDyna
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const useGetDynamicSecretDetails = ({
|
export const useGetDynamicSecretDetails = ({
|
||||||
projectId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
path,
|
path,
|
||||||
slug
|
slug
|
||||||
}: TDetailsDynamicSecretDTO) => {
|
}: TDetailsDynamicSecretDTO) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: dynamicSecretKeys.details({ path, environment, projectId, slug }),
|
queryKey: dynamicSecretKeys.details({ path, environment, projectSlug, slug }),
|
||||||
enabled: Boolean(projectId && environment && path && slug),
|
enabled: Boolean(projectSlug && environment && path && slug),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await apiRequest.get<{
|
const { data } = await apiRequest.get<{
|
||||||
dynamicSecret: TDynamicSecret & { inputs: unknown };
|
dynamicSecret: TDynamicSecret & { inputs: unknown };
|
||||||
}>(`/api/v1/dynamic-secrets/${slug}`, {
|
}>(`/api/v1/dynamic-secrets/${slug}`, {
|
||||||
params: {
|
params: {
|
||||||
projectId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export type TDynamicSecretProvider = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type TCreateDynamicSecretDTO = {
|
export type TCreateDynamicSecretDTO = {
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
provider: TDynamicSecretProvider;
|
provider: TDynamicSecretProvider;
|
||||||
defaultTTL: string;
|
defaultTTL: string;
|
||||||
maxTTL?: string;
|
maxTTL?: string;
|
||||||
@@ -51,7 +51,7 @@ export type TCreateDynamicSecretDTO = {
|
|||||||
|
|
||||||
export type TUpdateDynamicSecretDTO = {
|
export type TUpdateDynamicSecretDTO = {
|
||||||
slug: string;
|
slug: string;
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
data: {
|
data: {
|
||||||
@@ -63,20 +63,20 @@ export type TUpdateDynamicSecretDTO = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type TListDynamicSecretDTO = {
|
export type TListDynamicSecretDTO = {
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDeleteDynamicSecretDTO = {
|
export type TDeleteDynamicSecretDTO = {
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDetailsDynamicSecretDTO = {
|
export type TDetailsDynamicSecretDTO = {
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ export const useCreateDynamicSecretLease = () => {
|
|||||||
);
|
);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { path, environment, projectId, slug }) => {
|
onSuccess: (_, { path, environment, projectSlug, slug }) => {
|
||||||
queryClient.invalidateQueries(
|
queryClient.invalidateQueries(
|
||||||
dynamicSecretLeaseKeys.list({ path, projectId, environment, slug })
|
dynamicSecretLeaseKeys.list({ path, projectSlug, environment, slug })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -44,9 +44,9 @@ export const useRenewDynamicSecretLease = () => {
|
|||||||
);
|
);
|
||||||
return data.lease;
|
return data.lease;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { path, environment, projectId, slug }) => {
|
onSuccess: (_, { path, environment, projectSlug, slug }) => {
|
||||||
queryClient.invalidateQueries(
|
queryClient.invalidateQueries(
|
||||||
dynamicSecretLeaseKeys.list({ path, projectId, environment, slug })
|
dynamicSecretLeaseKeys.list({ path, projectSlug, environment, slug })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -63,9 +63,9 @@ export const useRevokeDynamicSecretLease = () => {
|
|||||||
);
|
);
|
||||||
return data.lease;
|
return data.lease;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { path, environment, projectId, slug }) => {
|
onSuccess: (_, { path, environment, projectSlug, slug }) => {
|
||||||
queryClient.invalidateQueries(
|
queryClient.invalidateQueries(
|
||||||
dynamicSecretLeaseKeys.list({ path, projectId, environment, slug })
|
dynamicSecretLeaseKeys.list({ path, projectSlug, environment, slug })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,26 +5,26 @@ import { apiRequest } from "@app/config/request";
|
|||||||
import { TDynamicSecretLease, TListDynamicSecretLeaseDTO } from "./types";
|
import { TDynamicSecretLease, TListDynamicSecretLeaseDTO } from "./types";
|
||||||
|
|
||||||
export const dynamicSecretLeaseKeys = {
|
export const dynamicSecretLeaseKeys = {
|
||||||
list: ({ projectId, environment, path, slug }: TListDynamicSecretLeaseDTO) =>
|
list: ({ projectSlug, environment, path, slug }: TListDynamicSecretLeaseDTO) =>
|
||||||
[{ projectId, environment, path, slug }, "dynamic-secret-leases"] as const
|
[{ projectSlug, environment, path, slug }, "dynamic-secret-leases"] as const
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetDynamicSecretLeases = ({
|
export const useGetDynamicSecretLeases = ({
|
||||||
projectId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
path,
|
path,
|
||||||
slug,
|
slug,
|
||||||
enabled = true
|
enabled = true
|
||||||
}: TListDynamicSecretLeaseDTO) => {
|
}: TListDynamicSecretLeaseDTO) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: dynamicSecretLeaseKeys.list({ path, environment, projectId, slug }),
|
queryKey: dynamicSecretLeaseKeys.list({ path, environment, projectSlug, slug }),
|
||||||
enabled: Boolean(projectId && environment && path && slug && enabled),
|
enabled: Boolean(projectSlug && environment && path && slug && enabled),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await apiRequest.get<{ leases: TDynamicSecretLease[] }>(
|
const { data } = await apiRequest.get<{ leases: TDynamicSecretLease[] }>(
|
||||||
`/api/v1/dynamic-secrets/leases/${slug}`,
|
`/api/v1/dynamic-secrets/${slug}/leases`,
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
projectId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export type TDynamicSecretLease = {
|
|||||||
|
|
||||||
export type TCreateDynamicSecretLeaseDTO = {
|
export type TCreateDynamicSecretLeaseDTO = {
|
||||||
slug: string;
|
slug: string;
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
ttl?: string;
|
ttl?: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
@@ -25,14 +25,14 @@ export type TRenewDynamicSecretLeaseDTO = {
|
|||||||
leaseId: string;
|
leaseId: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
ttl?: string;
|
ttl?: string;
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TListDynamicSecretLeaseDTO = {
|
export type TListDynamicSecretLeaseDTO = {
|
||||||
slug: string;
|
slug: string;
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
@@ -41,7 +41,7 @@ export type TListDynamicSecretLeaseDTO = {
|
|||||||
export type TRevokeDynamicSecretLeaseDTO = {
|
export type TRevokeDynamicSecretLeaseDTO = {
|
||||||
leaseId: string;
|
leaseId: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
path: string;
|
path: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ export const SecretMainPage = () => {
|
|||||||
// env slug
|
// env slug
|
||||||
const environment = router.query.env as string;
|
const environment = router.query.env as string;
|
||||||
const workspaceId = currentWorkspace?.id || "";
|
const workspaceId = currentWorkspace?.id || "";
|
||||||
|
const projectSlug = currentWorkspace?.slug || "";
|
||||||
const secretPath = (router.query.secretPath as string) || "/";
|
const secretPath = (router.query.secretPath as string) || "/";
|
||||||
const canReadSecret = permission.can(
|
const canReadSecret = permission.can(
|
||||||
ProjectPermissionActions.Read,
|
ProjectPermissionActions.Read,
|
||||||
@@ -139,7 +140,7 @@ export const SecretMainPage = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { data: dynamicSecrets, isLoading: isDynamicSecretLoading } = useGetDynamicSecrets({
|
const { data: dynamicSecrets, isLoading: isDynamicSecretLoading } = useGetDynamicSecrets({
|
||||||
projectId: workspaceId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
path: secretPath
|
path: secretPath
|
||||||
});
|
});
|
||||||
@@ -258,6 +259,7 @@ export const SecretMainPage = () => {
|
|||||||
importedSecrets={importedSecrets}
|
importedSecrets={importedSecrets}
|
||||||
environment={environment}
|
environment={environment}
|
||||||
workspaceId={workspaceId}
|
workspaceId={workspaceId}
|
||||||
|
projectSlug={projectSlug}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
isVisible={isVisible}
|
isVisible={isVisible}
|
||||||
filter={filter}
|
filter={filter}
|
||||||
@@ -316,7 +318,7 @@ export const SecretMainPage = () => {
|
|||||||
<DynamicSecretListView
|
<DynamicSecretListView
|
||||||
sortDir={sortDir}
|
sortDir={sortDir}
|
||||||
environment={environment}
|
environment={environment}
|
||||||
workspaceId={workspaceId}
|
projectSlug={projectSlug}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
dynamicSecrets={dynamicSecrets || []}
|
dynamicSecrets={dynamicSecrets || []}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -62,7 +62,9 @@ type Props = {
|
|||||||
// swtich the secrets type as it gets decrypted after api call
|
// swtich the secrets type as it gets decrypted after api call
|
||||||
importedSecrets?: Array<Omit<TImportedSecrets, "secrets"> & { secrets: DecryptedSecret[] }>;
|
importedSecrets?: Array<Omit<TImportedSecrets, "secrets"> & { secrets: DecryptedSecret[] }>;
|
||||||
environment: string;
|
environment: string;
|
||||||
|
// @depreciated will be moving all these details to zustand
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
|
projectSlug: string;
|
||||||
secretPath?: string;
|
secretPath?: string;
|
||||||
filter: Filter;
|
filter: Filter;
|
||||||
tags?: WsTag[];
|
tags?: WsTag[];
|
||||||
@@ -81,6 +83,7 @@ export const ActionBar = ({
|
|||||||
importedSecrets = [],
|
importedSecrets = [],
|
||||||
environment,
|
environment,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
projectSlug,
|
||||||
secretPath = "/",
|
secretPath = "/",
|
||||||
filter,
|
filter,
|
||||||
tags = [],
|
tags = [],
|
||||||
@@ -443,7 +446,7 @@ export const ActionBar = ({
|
|||||||
<CreateDynamicSecretForm
|
<CreateDynamicSecretForm
|
||||||
isOpen={popUp.addDynamicSecret.isOpen}
|
isOpen={popUp.addDynamicSecret.isOpen}
|
||||||
onToggle={(isOpen) => handlePopUpToggle("addDynamicSecret", isOpen)}
|
onToggle={(isOpen) => handlePopUpToggle("addDynamicSecret", isOpen)}
|
||||||
workspaceId={workspaceId}
|
projectSlug={projectSlug}
|
||||||
environment={environment}
|
environment={environment}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
/>
|
/>
|
||||||
|
|||||||
+3
-3
@@ -11,7 +11,7 @@ import { SqlDatabaseInputForm } from "./SqlDatabaseInputForm";
|
|||||||
type Props = {
|
type Props = {
|
||||||
isOpen?: boolean;
|
isOpen?: boolean;
|
||||||
onToggle: (isOpen: boolean) => void;
|
onToggle: (isOpen: boolean) => void;
|
||||||
workspaceId: string;
|
projectSlug:string;
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
};
|
};
|
||||||
@@ -24,7 +24,7 @@ enum WizardSteps {
|
|||||||
export const CreateDynamicSecretForm = ({
|
export const CreateDynamicSecretForm = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
onToggle,
|
onToggle,
|
||||||
workspaceId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
secretPath
|
secretPath
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
@@ -92,7 +92,7 @@ export const CreateDynamicSecretForm = ({
|
|||||||
<SqlDatabaseInputForm
|
<SqlDatabaseInputForm
|
||||||
onCompleted={handleFormReset}
|
onCompleted={handleFormReset}
|
||||||
onCancel={handleFormReset}
|
onCancel={handleFormReset}
|
||||||
projectId={workspaceId}
|
projectSlug={projectSlug}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
environment={environment}
|
environment={environment}
|
||||||
/>
|
/>
|
||||||
|
|||||||
+3
-3
@@ -58,7 +58,7 @@ type Props = {
|
|||||||
onCompleted: () => void;
|
onCompleted: () => void;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ export const SqlDatabaseInputForm = ({
|
|||||||
onCancel,
|
onCancel,
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
projectId
|
projectSlug
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -89,7 +89,7 @@ export const SqlDatabaseInputForm = ({
|
|||||||
slug,
|
slug,
|
||||||
path: secretPath,
|
path: secretPath,
|
||||||
defaultTTL,
|
defaultTTL,
|
||||||
projectId,
|
projectSlug,
|
||||||
environment
|
environment
|
||||||
});
|
});
|
||||||
onCompleted();
|
onCompleted();
|
||||||
|
|||||||
+20
-20
@@ -13,20 +13,6 @@ import { useTimedReset } from "@app/hooks";
|
|||||||
import { useCreateDynamicSecretLease } from "@app/hooks/api";
|
import { useCreateDynamicSecretLease } from "@app/hooks/api";
|
||||||
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
import { DynamicSecretProviders } from "@app/hooks/api/dynamicSecret/types";
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
ttl: z.string().refine((val) => ms(val) > 0, "TTL must be a positive number")
|
|
||||||
});
|
|
||||||
type TForm = z.infer<typeof formSchema>;
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
onClose: () => void;
|
|
||||||
slug: string;
|
|
||||||
provider: DynamicSecretProviders;
|
|
||||||
projectId: string;
|
|
||||||
environment: string;
|
|
||||||
secretPath: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const OutputDisplay = ({
|
const OutputDisplay = ({
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
@@ -68,14 +54,14 @@ const OutputDisplay = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderOutputForm = (provider: DynamicSecretProviders, data: unknown) => {
|
const renderOutputForm = (provider: DynamicSecretProviders, data: unknown) => {
|
||||||
const { username, password } = data as { username: string; password: string };
|
const { DB_PASSWORD, DB_USERNAME } = data as { DB_USERNAME: string; DB_PASSWORD: string };
|
||||||
if (provider === DynamicSecretProviders.SqlDatabase) {
|
if (provider === DynamicSecretProviders.SqlDatabase) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<OutputDisplay label="Database User" value={username} />
|
<OutputDisplay label="Database User" value={DB_USERNAME} />
|
||||||
<OutputDisplay
|
<OutputDisplay
|
||||||
label="Database Password"
|
label="Database Password"
|
||||||
value={password}
|
value={DB_PASSWORD}
|
||||||
helperText="Important: Copy this information now. It will disappear after this.opy this values as you won't be able to see it again."
|
helperText="Important: Copy this information now. It will disappear after this.opy this values as you won't be able to see it again."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,9 +70,23 @@ const renderOutputForm = (provider: DynamicSecretProviders, data: unknown) => {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const formSchema = z.object({
|
||||||
|
ttl: z.string().refine((val) => ms(val) > 0, "TTL must be a positive number")
|
||||||
|
});
|
||||||
|
type TForm = z.infer<typeof formSchema>;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
onClose: () => void;
|
||||||
|
slug: string;
|
||||||
|
provider: DynamicSecretProviders;
|
||||||
|
projectSlug: string;
|
||||||
|
environment: string;
|
||||||
|
secretPath: string;
|
||||||
|
};
|
||||||
|
|
||||||
export const CreateDynamicSecretLease = ({
|
export const CreateDynamicSecretLease = ({
|
||||||
onClose,
|
onClose,
|
||||||
projectId,
|
projectSlug,
|
||||||
slug,
|
slug,
|
||||||
provider,
|
provider,
|
||||||
secretPath,
|
secretPath,
|
||||||
@@ -107,11 +107,11 @@ export const CreateDynamicSecretLease = ({
|
|||||||
const createDynamicSecretLease = useCreateDynamicSecretLease();
|
const createDynamicSecretLease = useCreateDynamicSecretLease();
|
||||||
|
|
||||||
const handleDynamicSecretLeaseCreate = async ({ ttl }: TForm) => {
|
const handleDynamicSecretLeaseCreate = async ({ ttl }: TForm) => {
|
||||||
if(createDynamicSecretLease.isLoading) return;
|
if (createDynamicSecretLease.isLoading) return;
|
||||||
try {
|
try {
|
||||||
await createDynamicSecretLease.mutateAsync({
|
await createDynamicSecretLease.mutateAsync({
|
||||||
environment,
|
environment,
|
||||||
projectId,
|
projectSlug,
|
||||||
path: secretPath,
|
path: secretPath,
|
||||||
ttl,
|
ttl,
|
||||||
slug
|
slug
|
||||||
|
|||||||
+5
-5
@@ -28,7 +28,7 @@ import { RenewDynamicSecretLease } from "./RenewDynamicSecretLease";
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
slug: string;
|
slug: string;
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
onClickNewLease: () => void;
|
onClickNewLease: () => void;
|
||||||
@@ -36,7 +36,7 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const DynamicSecretLease = ({
|
export const DynamicSecretLease = ({
|
||||||
projectId,
|
projectSlug,
|
||||||
slug,
|
slug,
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
@@ -48,7 +48,7 @@ export const DynamicSecretLease = ({
|
|||||||
"renewSecret"
|
"renewSecret"
|
||||||
] as const);
|
] as const);
|
||||||
const { data: leases, isLoading: isLeaseLoading } = useGetDynamicSecretLeases({
|
const { data: leases, isLoading: isLeaseLoading } = useGetDynamicSecretLeases({
|
||||||
projectId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
path: secretPath,
|
path: secretPath,
|
||||||
slug
|
slug
|
||||||
@@ -62,7 +62,7 @@ export const DynamicSecretLease = ({
|
|||||||
const { leaseId } = popUp.deleteSecret.data as { leaseId: string };
|
const { leaseId } = popUp.deleteSecret.data as { leaseId: string };
|
||||||
await deleteDynamicSecretLease.mutateAsync({
|
await deleteDynamicSecretLease.mutateAsync({
|
||||||
environment,
|
environment,
|
||||||
projectId,
|
projectSlug,
|
||||||
path: secretPath,
|
path: secretPath,
|
||||||
slug,
|
slug,
|
||||||
leaseId
|
leaseId
|
||||||
@@ -193,7 +193,7 @@ export const DynamicSecretLease = ({
|
|||||||
<ModalContent title="Renew Lease">
|
<ModalContent title="Renew Lease">
|
||||||
<RenewDynamicSecretLease
|
<RenewDynamicSecretLease
|
||||||
onClose={() => handlePopUpClose("renewSecret")}
|
onClose={() => handlePopUpClose("renewSecret")}
|
||||||
projectId={projectId}
|
projectSlug={projectSlug}
|
||||||
leaseId={(popUp.renewSecret?.data as { leaseId: string })?.leaseId}
|
leaseId={(popUp.renewSecret?.data as { leaseId: string })?.leaseId}
|
||||||
slug={slug}
|
slug={slug}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
|
|||||||
+6
-6
@@ -40,7 +40,7 @@ const formatProviderName = (type: DynamicSecretProviders) => {
|
|||||||
type Props = {
|
type Props = {
|
||||||
dynamicSecrets: TDynamicSecret[];
|
dynamicSecrets: TDynamicSecret[];
|
||||||
environment: string;
|
environment: string;
|
||||||
workspaceId: string;
|
projectSlug: string;
|
||||||
secretPath?: string;
|
secretPath?: string;
|
||||||
sortDir: SortDir;
|
sortDir: SortDir;
|
||||||
};
|
};
|
||||||
@@ -48,7 +48,7 @@ type Props = {
|
|||||||
export const DynamicSecretListView = ({
|
export const DynamicSecretListView = ({
|
||||||
dynamicSecrets = [],
|
dynamicSecrets = [],
|
||||||
environment,
|
environment,
|
||||||
workspaceId,
|
projectSlug,
|
||||||
secretPath = "/",
|
secretPath = "/",
|
||||||
sortDir = SortDir.ASC
|
sortDir = SortDir.ASC
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
@@ -67,7 +67,7 @@ export const DynamicSecretListView = ({
|
|||||||
const { slug } = popUp.deleteDynamicSecret.data as TDynamicSecret;
|
const { slug } = popUp.deleteDynamicSecret.data as TDynamicSecret;
|
||||||
await deleteDynamicSecret.mutateAsync({
|
await deleteDynamicSecret.mutateAsync({
|
||||||
environment,
|
environment,
|
||||||
projectId: workspaceId,
|
projectSlug,
|
||||||
path: secretPath,
|
path: secretPath,
|
||||||
slug
|
slug
|
||||||
});
|
});
|
||||||
@@ -206,7 +206,7 @@ export const DynamicSecretListView = ({
|
|||||||
<DynamicSecretLease
|
<DynamicSecretLease
|
||||||
onClickNewLease={() => handlePopUpOpen("createDynamicSecretLease", secret)}
|
onClickNewLease={() => handlePopUpOpen("createDynamicSecretLease", secret)}
|
||||||
onClose={() => handlePopUpClose("dynamicSecretLeases")}
|
onClose={() => handlePopUpClose("dynamicSecretLeases")}
|
||||||
projectId={workspaceId}
|
projectSlug={projectSlug}
|
||||||
key={secret.id}
|
key={secret.id}
|
||||||
slug={secret.slug}
|
slug={secret.slug}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
@@ -226,7 +226,7 @@ export const DynamicSecretListView = ({
|
|||||||
(popUp.createDynamicSecretLease?.data as { type: DynamicSecretProviders })?.type
|
(popUp.createDynamicSecretLease?.data as { type: DynamicSecretProviders })?.type
|
||||||
}
|
}
|
||||||
onClose={() => handlePopUpClose("createDynamicSecretLease")}
|
onClose={() => handlePopUpClose("createDynamicSecretLease")}
|
||||||
projectId={workspaceId}
|
projectSlug={projectSlug}
|
||||||
slug={(popUp.createDynamicSecretLease?.data as { slug: string })?.slug}
|
slug={(popUp.createDynamicSecretLease?.data as { slug: string })?.slug}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
environment={environment}
|
environment={environment}
|
||||||
@@ -240,7 +240,7 @@ export const DynamicSecretListView = ({
|
|||||||
<ModalContent title="Edit dynamic secret" className="max-w-3xl">
|
<ModalContent title="Edit dynamic secret" className="max-w-3xl">
|
||||||
<EditDynamicSecretForm
|
<EditDynamicSecretForm
|
||||||
onClose={() => handlePopUpClose("updateDynamicSecret")}
|
onClose={() => handlePopUpClose("updateDynamicSecret")}
|
||||||
projectId={workspaceId}
|
projectSlug={projectSlug}
|
||||||
slug={(popUp.updateDynamicSecret?.data as TDynamicSecret)?.slug}
|
slug={(popUp.updateDynamicSecret?.data as TDynamicSecret)?.slug}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
environment={environment}
|
environment={environment}
|
||||||
|
|||||||
+4
-4
@@ -9,7 +9,7 @@ import { EditDynamicSecretSqlProviderForm } from "./EditDynamicSecretSqlProvider
|
|||||||
type Props = {
|
type Props = {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
slug: string;
|
slug: string;
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
};
|
};
|
||||||
@@ -17,13 +17,13 @@ type Props = {
|
|||||||
export const EditDynamicSecretForm = ({
|
export const EditDynamicSecretForm = ({
|
||||||
slug,
|
slug,
|
||||||
environment,
|
environment,
|
||||||
projectId,
|
projectSlug,
|
||||||
onClose,
|
onClose,
|
||||||
secretPath
|
secretPath
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const { data: dynamicSecretDetails, isLoading: isDynamicSecretLoading } =
|
const { data: dynamicSecretDetails, isLoading: isDynamicSecretLoading } =
|
||||||
useGetDynamicSecretDetails({
|
useGetDynamicSecretDetails({
|
||||||
projectId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
slug,
|
slug,
|
||||||
path: secretPath
|
path: secretPath
|
||||||
@@ -49,7 +49,7 @@ export const EditDynamicSecretForm = ({
|
|||||||
>
|
>
|
||||||
<EditDynamicSecretSqlProviderForm
|
<EditDynamicSecretSqlProviderForm
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
projectId={projectId}
|
projectSlug={projectSlug}
|
||||||
secretPath={secretPath}
|
secretPath={secretPath}
|
||||||
dynamicSecret={dynamicSecretDetails}
|
dynamicSecret={dynamicSecretDetails}
|
||||||
environment={environment}
|
environment={environment}
|
||||||
|
|||||||
+3
-3
@@ -61,8 +61,8 @@ type Props = {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
dynamicSecret: TDynamicSecret & { inputs: unknown };
|
dynamicSecret: TDynamicSecret & { inputs: unknown };
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
projectId: string;
|
|
||||||
environment: string;
|
environment: string;
|
||||||
|
projectSlug: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EditDynamicSecretSqlProviderForm = ({
|
export const EditDynamicSecretSqlProviderForm = ({
|
||||||
@@ -70,7 +70,7 @@ export const EditDynamicSecretSqlProviderForm = ({
|
|||||||
dynamicSecret,
|
dynamicSecret,
|
||||||
environment,
|
environment,
|
||||||
secretPath,
|
secretPath,
|
||||||
projectId
|
projectSlug
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -97,7 +97,7 @@ export const EditDynamicSecretSqlProviderForm = ({
|
|||||||
await updateDynamicSecret.mutateAsync({
|
await updateDynamicSecret.mutateAsync({
|
||||||
slug: dynamicSecret.slug,
|
slug: dynamicSecret.slug,
|
||||||
path: secretPath,
|
path: secretPath,
|
||||||
projectId,
|
projectSlug,
|
||||||
environment,
|
environment,
|
||||||
data: {
|
data: {
|
||||||
maxTTL: maxTTL || undefined,
|
maxTTL: maxTTL || undefined,
|
||||||
|
|||||||
+3
-3
@@ -25,14 +25,14 @@ type Props = {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
leaseId: string;
|
leaseId: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
projectId: string;
|
projectSlug: string;
|
||||||
environment: string;
|
environment: string;
|
||||||
secretPath: string;
|
secretPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RenewDynamicSecretLease = ({
|
export const RenewDynamicSecretLease = ({
|
||||||
onClose,
|
onClose,
|
||||||
projectId,
|
projectSlug,
|
||||||
slug,
|
slug,
|
||||||
leaseId,
|
leaseId,
|
||||||
secretPath,
|
secretPath,
|
||||||
@@ -57,7 +57,7 @@ export const RenewDynamicSecretLease = ({
|
|||||||
try {
|
try {
|
||||||
await renewDynamicSecretLease.mutateAsync({
|
await renewDynamicSecretLease.mutateAsync({
|
||||||
environment,
|
environment,
|
||||||
projectId,
|
projectSlug,
|
||||||
path: secretPath,
|
path: secretPath,
|
||||||
ttl,
|
ttl,
|
||||||
slug,
|
slug,
|
||||||
|
|||||||
Reference in New Issue
Block a user